mediawiki-extensions-Popups/webpack.config.js
Thiemo Kreuz c281bb9302 Clean up code enabling individual popup types
We still have 2 different mechanisms in place, maybe even 3:
* We simplify the CSS selector when we know a popup type is
  disabled, and it's impossible an anonymous user can enable it
  at run-time.
* We create that "initiallyEnabled" map that allows anonymous
  users to toggle the individual popup types at run-time.
* This map is also used to check if the footer link should be
  shown.
* There is also a wgPopupsReferencePreviews global that acts as
  a "kill switch". However, this is not a pure feature flag,
  but incorporates the user setting for registered users. This
  is currently partly redundant (checking
  `mw.user.options.get( 'popupsreferencepreviews' )` does the
  same) and can be removed later when the feature flag is not
  needed any more.

The footer link currently acts odd because anonymous users are
unable to enable ReferencePreviews, but get the footer link.

This patch introduces a 3-state model:
* `true` acts as before.
* `false` means a popup type is disabled, but anonymous users
  can enable it (i.e. this is the opt-out behavior for anonymous
  users).
* `null` means a popup type is not available at run-time, for
  nobody. Anonymous users can't do anything about this.
  Registered users must leave the page and change a setting.

Bug: T277640
Change-Id: Id8d1396c09cf0f706034a66f9cd3c880a8b33df8
2021-04-21 19:38:25 +02:00

122 lines
3.8 KiB
JavaScript

/* eslint-env node */
const { CleanWebpackPlugin } = require( 'clean-webpack-plugin' );
const path = require( 'path' );
const PUBLIC_PATH = '/w/extensions/Popups';
const distDir = path.resolve( __dirname, 'resources/dist' );
// The extension used for source map files.
const srcMapExt = '.map.json';
module.exports = ( env, argv ) => ( {
// Apply the rule of silence: https://wikipedia.org/wiki/Unix_philosophy.
stats: {
all: false,
// Output a timestamp when a build completes. Useful when watching files.
builtAt: true,
errors: true,
warnings: true
},
// Fail on the first build error instead of tolerating it for prod builds. This seems to
// correspond to optimization.noEmitOnErrors.
bail: argv.mode === 'production',
// Specify that all paths are relative the Webpack configuration directory not the current
// working directory.
context: __dirname,
entry: { index: './src' },
resolve: {
alias: {
redux: path.resolve(
__dirname,
argv.mode === 'production' ?
'node_modules/redux/dist/redux.min.js' :
'node_modules/redux/dist/redux.js'
),
'redux-thunk': path.resolve(
__dirname,
argv.mode === 'production' ?
'node_modules/redux-thunk/dist/redux-thunk.min.js' :
'node_modules/redux-thunk/dist/redux-thunk.js'
)
}
},
module: {
rules: [ {
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
// Beware of https://github.com/babel/babel-loader/issues/690. Changes to browsers require
// manual invalidation.
cacheDirectory: true
}
}
}, {
test: /\.svg$/,
loader: 'svg-inline-loader',
options: {
removeSVGTagAttrs: false // Keep width and height attributes.
}
} ]
},
optimization: {
// Don't produce production output when a build error occurs.
noEmitOnErrors: argv.mode === 'production',
// Use filenames instead of unstable numerical identifiers for file references. This
// increases the gzipped bundle size some but makes the build products easier to debug and
// appear deterministic. I.e., code changes will only alter the bundle they're packed in
// instead of shifting the identifiers in other bundles.
// https://webpack.js.org/guides/caching/#deterministic-hashes (namedModules replaces NamedModulesPlugin.)
namedModules: true
},
output: {
// Specify the destination of all build products.
path: distDir,
// Store outputs per module in files named after the modules. For the JavaScript entry
// itself, append .js to each ResourceLoader module entry name. This value is tightly
// coupled to sourceMapFilename.
filename: '[name].js',
// Rename source map extensions. Per T173491 files with a .map extension cannot be served
// from prod.
sourceMapFilename: `[file]${srcMapExt}`,
devtoolModuleFilenameTemplate: `${PUBLIC_PATH}/[resource-path]`
},
// Accurate source maps at the expense of build time. The source map is intentionally exposed
// to users via sourceMapFilename for prod debugging. This goes against convention as source
// code is publicly distributed.
devtool: 'source-map',
plugins: [
// Delete the output directory on each build.
new CleanWebpackPlugin( {
cleanOnceBeforeBuildPatterns: [ '**/*', '!.eslintrc.json' ]
} )
],
performance: {
// Size violations for prod builds fail; development builds are unchecked.
hints: argv.mode === 'production' ? 'error' : false,
// Minified uncompressed size limits for chunks / assets and entrypoints. Keep these numbers
// up-to-date and rounded to the nearest 10th of a kibibyte so that code sizing costs are
// well understood. Related to bundlesize minified, gzipped compressed file size tests.
maxAssetSize: 44.1 * 1024,
maxEntrypointSize: 44.1 * 1024,
// The default filter excludes map files but we rename ours.
assetFilter: ( filename ) => !filename.endsWith( srcMapExt )
}
} );