e98559c3ff
This implementation is a bit smaller and still has the following benefits: * No need of app/javascript/packs/custom.js For custom stylesheet, it typically has only "require('../styles/custom.scss')" and is redundant. * No need to extract vendor stylesheet to another asset Extracting vendor stylesheet could be forgotten by developers who do not use custom stylesheet.
89 lines
2.9 KiB
JavaScript
89 lines
2.9 KiB
JavaScript
// Note: You must restart bin/webpack-dev-server for changes to take effect
|
|
|
|
/* eslint global-require: 0 */
|
|
/* eslint import/no-dynamic-require: 0 */
|
|
|
|
const { existsSync } = require('fs');
|
|
const webpack = require('webpack');
|
|
const { basename, dirname, join, relative, resolve, sep } = require('path');
|
|
const { sync } = require('glob');
|
|
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
|
const ManifestPlugin = require('webpack-manifest-plugin');
|
|
const extname = require('path-complete-extname');
|
|
const { env, paths, publicPath, loadersDir } = require('./configuration.js');
|
|
const localePackPaths = require('./generateLocalePacks');
|
|
|
|
const extensionGlob = `**/*{${paths.extensions.join(',')}}*`;
|
|
const packPaths = sync(join(paths.source, paths.entry, extensionGlob));
|
|
const entryPacks = [].concat(packPaths).concat(localePackPaths);
|
|
|
|
const customApplicationStyle = resolve(join(paths.source, 'styles/custom.scss'));
|
|
const originalApplicationStyle = resolve(join(paths.source, 'styles/application.scss'));
|
|
|
|
module.exports = {
|
|
entry: entryPacks.reduce(
|
|
(map, entry) => {
|
|
const localMap = map;
|
|
let namespace = relative(join(paths.source, paths.entry), dirname(entry));
|
|
if (namespace === join('..', '..', '..', 'tmp', 'packs')) {
|
|
namespace = ''; // generated by generateLocalePacks.js
|
|
}
|
|
localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry);
|
|
return localMap;
|
|
}, {}
|
|
),
|
|
|
|
output: {
|
|
filename: '[name].js',
|
|
chunkFilename: '[name]-[chunkhash].js',
|
|
path: resolve(paths.output, paths.entry),
|
|
publicPath,
|
|
},
|
|
|
|
module: {
|
|
rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)),
|
|
},
|
|
|
|
plugins: [
|
|
new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
|
|
new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[hash].css' : '[name].css'),
|
|
new ManifestPlugin({ fileName: paths.manifest, publicPath, writeToFileEmit: true }),
|
|
new webpack.optimize.CommonsChunkPlugin({
|
|
name: 'common',
|
|
minChunks: (module, count) => {
|
|
const reactIntlPathRegexp = new RegExp(`node_modules\\${sep}react-intl`);
|
|
|
|
if (module.resource && reactIntlPathRegexp.test(module.resource)) {
|
|
// skip react-intl because it's useless to put in the common chunk,
|
|
// e.g. because "shared" modules between zh-TW and zh-CN will never
|
|
// be loaded together
|
|
return false;
|
|
}
|
|
|
|
return count >= 2;
|
|
},
|
|
}),
|
|
],
|
|
|
|
resolve: {
|
|
alias: {
|
|
'mastodon-application-style': existsSync(customApplicationStyle) ?
|
|
customApplicationStyle : originalApplicationStyle,
|
|
},
|
|
extensions: paths.extensions,
|
|
modules: [
|
|
resolve(paths.source),
|
|
resolve(paths.node_modules),
|
|
],
|
|
},
|
|
|
|
resolveLoader: {
|
|
modules: [paths.node_modules],
|
|
},
|
|
|
|
node: {
|
|
// Called by http-link-header in an API we never use, increases
|
|
// bundle size unnecessarily
|
|
Buffer: false,
|
|
},
|
|
};
|