Skip to content

Commit a9a7d69

Browse files
committed
Multicompilation of indexXX.js files to indexXX.html outputs
1 parent cccd855 commit a9a7d69

File tree

4 files changed

+60
-15
lines changed

4 files changed

+60
-15
lines changed

packages/react-scripts/config/webpack.config.dev.js

+25-6
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ const env = getClientEnvironment(publicUrl);
3535
// This is the development configuration.
3636
// It is focused on developer experience and fast rebuilds.
3737
// The production configuration is different and lives in a separate file.
38-
module.exports = {
38+
const configure = indexName => ({
39+
// Name in compilation output log when multiple entry files are used.
40+
name: `${indexName}.html`,
3941
// You may want 'eval' instead if you prefer to see the compiled output in DevTools.
4042
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.
4143
devtool: 'cheap-module-source-map',
@@ -58,8 +60,8 @@ module.exports = {
5860
require.resolve('./polyfills'),
5961
// Errors should be considered fatal in development
6062
require.resolve('react-error-overlay'),
61-
// Finally, this is your app's code:
62-
paths.appIndexJs,
63+
// Finally, this is your app's code, depending on entry index file:
64+
paths.appIndexJs.replace('index', indexName),
6365
// We include the app code last so that if there is a runtime error during
6466
// initialization, it doesn't blow up the WebpackDevServer client, and
6567
// changing JS code would still trigger a refresh.
@@ -72,9 +74,13 @@ module.exports = {
7274
// This does not produce a real file. It's just the virtual path that is
7375
// served by WebpackDevServer in development. This is the JS bundle
7476
// containing code from all our entry points, and the Webpack runtime.
75-
filename: 'static/js/bundle.js',
77+
filename: indexName === 'index'
78+
? 'static/js/bundle.js'
79+
: `static/js/${indexName}-bundle.js`,
7680
// There are also additional JS chunk files if you use code splitting.
77-
chunkFilename: 'static/js/[name].chunk.js',
81+
chunkFilename: indexName === 'index'
82+
? 'static/js/[name].chunk.js'
83+
: `static/js/${indexName}-[name].chunk.js`,
7884
// This is the URL that app is served from. We use "/" in development.
7985
publicPath: publicPath,
8086
// Point sourcemap entries to original disk location
@@ -246,6 +252,7 @@ module.exports = {
246252
new InterpolateHtmlPlugin(env.raw),
247253
// Generates an `index.html` file with the <script> injected.
248254
new HtmlWebpackPlugin({
255+
filename: `${indexName}.html`,
249256
inject: true,
250257
template: paths.appHtml,
251258
}),
@@ -285,4 +292,16 @@ module.exports = {
285292
performance: {
286293
hints: false,
287294
},
288-
};
295+
});
296+
297+
// Read potential indexXX.js candidates from src/ at this point.
298+
const fs = require('fs');
299+
const indexFiles = fs.readdirSync(paths.appSrc).filter(file => {
300+
// Takes all indexXX.js files. Does not check validity at this point, could be a directory and crash.
301+
return path.basename(file).startsWith('index') &&
302+
path.extname(file) === '.js';
303+
});
304+
305+
// Returns an array of configurations to trigger webpack multicompilation
306+
module.exports = indexFiles.map(indexFile =>
307+
configure(path.parse(indexFile).name));

packages/react-scripts/config/webpack.config.prod.js

+28-6
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,19 @@ const extractTextPluginOptions = shouldUseRelativeAssetPaths
5757
// This is the production configuration.
5858
// It compiles slowly and is focused on producing a fast and minimal bundle.
5959
// The development configuration is different and lives in a separate file.
60-
module.exports = {
60+
const configure = indexName => ({
61+
// Name in compilation output log when multiple entry files are used.
62+
name: `${indexName}.html`,
6163
// Don't attempt to continue if there are any errors.
6264
bail: true,
6365
// We generate sourcemaps in production. This is slow but gives good results.
6466
// You can exclude the *.map files from the build during deployment.
6567
devtool: 'source-map',
6668
// In production, we only want to load the polyfills and the app code.
67-
entry: [require.resolve('./polyfills'), paths.appIndexJs],
69+
entry: [
70+
require.resolve('./polyfills'),
71+
paths.appIndexJs.replace('index', indexName),
72+
],
6873
output: {
6974
// The build folder.
7075
path: paths.appBuild,
@@ -258,6 +263,7 @@ module.exports = {
258263
new InterpolateHtmlPlugin(env.raw),
259264
// Generates an `index.html` file with the <script> injected.
260265
new HtmlWebpackPlugin({
266+
filename: `${indexName}.html`,
261267
inject: true,
262268
template: paths.appHtml,
263269
minify: {
@@ -301,7 +307,9 @@ module.exports = {
301307
// to their corresponding output file so that tools can pick it up without
302308
// having to parse `index.html`.
303309
new ManifestPlugin({
304-
fileName: 'asset-manifest.json',
310+
fileName: indexName === 'index'
311+
? 'asset-manifest.json'
312+
: `${indexName}-asset-manifest.json`,
305313
}),
306314
// Generate a service worker script that will precache, and keep up to date,
307315
// the HTML & assets that are part of the Webpack build.
@@ -311,7 +319,9 @@ module.exports = {
311319
// If a URL is already hashed by Webpack, then there is no concern
312320
// about it being stale, and the cache-busting can be skipped.
313321
dontCacheBustUrlsMatching: /\.\w{8}\./,
314-
filename: 'service-worker.js',
322+
fileName: indexName === 'index'
323+
? 'service-worker.js'
324+
: `${indexName}-service-worker.js`,
315325
logger(message) {
316326
if (message.indexOf('Total precache size is') === 0) {
317327
// This message occurs for every build and is a bit too noisy.
@@ -321,7 +331,7 @@ module.exports = {
321331
},
322332
minify: true,
323333
// For unknown URLs, fallback to the index page
324-
navigateFallback: publicUrl + '/index.html',
334+
navigateFallback: `${publicUrl}/${indexName}.html`,
325335
// Ignores URLs starting from /__ (useful for Firebase):
326336
// https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
327337
navigateFallbackWhitelist: [/^(?!\/__).*/],
@@ -345,4 +355,16 @@ module.exports = {
345355
net: 'empty',
346356
tls: 'empty',
347357
},
348-
};
358+
});
359+
360+
// Read potential indexXX.js candidates from src/ at this point.
361+
const fs = require('fs');
362+
const indexFiles = fs.readdirSync(paths.appSrc).filter(file => {
363+
// Takes all indexXX.js files. Does not check validity at this point, could be a directory and crash.
364+
return path.basename(file).startsWith('index') &&
365+
path.extname(file) === '.js';
366+
});
367+
368+
// Returns an array of configurations to trigger webpack multicompilation
369+
module.exports = indexFiles.map(indexFile =>
370+
configure(path.parse(indexFile).name));

packages/react-scripts/config/webpackDevServer.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ module.exports = function(proxy, allowedHost) {
6868
hot: true,
6969
// It is important to tell WebpackDevServer to use the same "root" path
7070
// as we specified in the config. In development, we always serve from /.
71-
publicPath: config.output.publicPath,
71+
publicPath: (config[0] || config).output.publicPath,
7272
// WebpackDevServer is noisy by default so we emit custom message instead
7373
// by listening to the compiler events with `compiler.plugin` calls above.
7474
quiet: true,

packages/react-scripts/scripts/build.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,16 @@ measureFileSizesBeforeBuild(paths.appBuild)
7676
}
7777

7878
console.log('File sizes after gzip:\n');
79-
printFileSizesAfterBuild(stats, previousFileSizes, paths.appBuild);
79+
// Webpack multicompilation produces an array of stats
80+
(stats.stats || [stats]).forEach(stats => {
81+
console.log(` ${stats.compilation.name}:`);
82+
printFileSizesAfterBuild(stats, previousFileSizes, paths.appBuild);
83+
});
8084
console.log();
8185

8286
const appPackage = require(paths.appPackageJson);
8387
const publicUrl = paths.publicUrl;
84-
const publicPath = config.output.publicPath;
88+
const publicPath = (config[0] || config).output.publicPath;
8589
const buildFolder = path.relative(process.cwd(), paths.appBuild);
8690
printHostingInstructions(
8791
appPackage,

0 commit comments

Comments
 (0)