Created
December 27, 2018 15:41
-
-
Save evanpurkhiser/e0ef9b4602aa0941e1deb3bb2fe77eea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const localeCatalog = JSON.parse(fs.readFileSync(localeCatalogPath, 'utf8')); | |
// moment uses a lowercase IETF language tag, while django uses the underscore | |
// with uppercase syntax | |
const normalizeLocale = locale => locale.toLowerCase().replace('_', '-'); | |
const supportedLocales = localeCatalog.supported_locales; | |
const normalizedSuppotedLocales = supportedLocales.map(normalizeLocale); | |
// A mapping of chunk groups used for locale code splitting | |
const localeChunkGroups = {}; | |
// No need to split the english locale out as it will be completely empty and | |
// is not included by the django layout.html | |
const chunkedLocales = supportedLocales.filter(l => l !== 'en'); | |
for (const locale of chunkedLocales) { | |
const normalizedLocale = normalizeLocale(locale); | |
const group = `locale/${locale}`; | |
// Modify this list of tests to include other modules that should be chunked | |
// with each locale. | |
const localeGroupTests = [ | |
new RegExp(`locale\\/${locale}\\/.*\\.po$`), | |
new RegExp(`moment\\/locale\\/${normalizedLocale}\\.js$`), | |
]; | |
// module test taken from [0] and modified to support testing against | |
// multiple expressions. | |
// | |
// [0] https://github.com/webpack/webpack/blob/7a6a71f1e9349f86833de12a673805621f0fc6f6/lib/optimize/SplitChunksPlugin.js#L309-L320 | |
const groupTest = module => | |
localeGroupTests.some( | |
pattern => | |
module.nameForCondition && pattern.test(module.nameForCondition()) | |
? true | |
: Array.from(module.chunksIterable).some(c => c.name && pattern.test(c.name)) | |
); | |
localeChunkGroups[group] = { | |
name: group, | |
test: groupTest, | |
enforce: true, | |
}; | |
} | |
// Restirct translation files that are pulled in through app/translations.jsx | |
// and through moment/locale/* to only those which we create bundles for via | |
// locale/catalogs.json. | |
const localeRestrictionPlugins = [ | |
new webpack.ContextReplacementPlugin( | |
/sentry-locale$/, | |
path.join(__dirname, 'src', 'sentry', 'locale', path.sep), | |
true, | |
new RegExp(`(${supportedLocales.join('|')})/.*\\.po$`) | |
), | |
new webpack.ContextReplacementPlugin( | |
/moment\/locale/, | |
new RegExp(`(${normalizedSuppotedLocales.join('|')})\\.js$`) | |
), | |
]; | |
/** | |
* Explicit codesplitting cache groups | |
*/ | |
const cacheGroups = { | |
vendors: { | |
enforce: true, | |
name: 'vendor', | |
test: /[\\/]node_modules[\\/]/, | |
priority: -10, | |
}, | |
...localeChunkGroups, | |
}; | |
/** | |
* Main Webpack config for Sentry React SPA. | |
*/ | |
const appConfig = { | |
mode: WEBPACK_MODE, | |
entry: {app: 'app'}, | |
context: path.join(__dirname, staticPrefix), | |
module: { | |
rules: [ | |
{ | |
test: /\.jsx?$/, | |
loader: 'babel-loader', | |
include: path.join(__dirname, staticPrefix), | |
exclude: /(vendor|node_modules|dist)/, | |
query: babelConfig, | |
}, | |
{ | |
test: /\.po$/, | |
loader: 'po-catalog-loader', | |
query: { | |
referenceExtensions: ['.js', '.jsx'], | |
domain: 'sentry', | |
}, | |
}, | |
{ | |
test: /app\/icons\/.*\.svg$/, | |
use: [{loader: 'svg-sprite-loader'}, {loader: 'svgo-loader'}], | |
}, | |
{ | |
test: /\.css/, | |
use: [{loader: 'style-loader'}, {loader: 'css-loader'}], | |
}, | |
{ | |
test: /\.(woff|woff2|ttf|eot|svg|png|gif|ico|jpg)($|\?)/, | |
exclude: /app\/icons\/.*\.svg$/, | |
use: [ | |
{ | |
loader: 'file-loader', | |
options: { | |
name: '[name].[ext]', | |
}, | |
}, | |
], | |
}, | |
], | |
noParse: [ | |
// don't parse known, pre-built javascript files (improves webpack perf) | |
/dist\/jquery\.js/, | |
/jed\/jed\.js/, | |
/marked\/lib\/marked\.js/, | |
], | |
}, | |
plugins: [ | |
new LodashModuleReplacementPlugin({ | |
collections: true, | |
currying: true, // these are enabled to support lodash/fp/ features | |
flattening: true, // used by a dependency of react-mentions | |
shorthands: true, | |
}), | |
new webpack.ProvidePlugin({ | |
$: 'jquery', | |
jQuery: 'jquery', | |
'window.jQuery': 'jquery', | |
'root.jQuery': 'jquery', | |
}), | |
new ExtractTextPlugin(), | |
new webpack.DefinePlugin({ | |
'process.env': { | |
NODE_ENV: JSON.stringify(process.env.NODE_ENV), | |
IS_PERCY: JSON.stringify( | |
process.env.CI && !!process.env.PERCY_TOKEN && !!process.env.TRAVIS | |
), | |
}, | |
}), | |
...localeRestrictionPlugins, | |
new BundleAnalyzerPlugin(), | |
], | |
resolve: { | |
alias: { | |
app: path.join(__dirname, 'src', 'sentry', 'static', 'sentry', 'app'), | |
'app-test': path.join(__dirname, 'tests', 'js'), | |
'app-test-helpers': path.join(__dirname, 'tests', 'js', 'helpers'), | |
'sentry-locale': path.join(__dirname, 'src', 'sentry', 'locale'), | |
'integration-docs-platforms': IS_TEST | |
? path.join(__dirname, 'tests/fixtures/integration-docs/_platforms.json') | |
: path.join(__dirname, 'src/sentry/integration-docs/_platforms.json'), | |
}, | |
modules: [path.join(__dirname, staticPrefix), 'node_modules'], | |
extensions: ['.jsx', '.js', '.json'], | |
}, | |
output: { | |
path: distPath, | |
filename: '[name].js', | |
libraryTarget: 'var', | |
library: 'exports', | |
sourceMapFilename: '[name].js.map', | |
}, | |
optimization: { | |
splitChunks: { | |
chunks: 'all', | |
cacheGroups, | |
}, | |
}, | |
devtool: IS_PRODUCTION ? 'source-map' : false, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment