Inline the webpack runtime chunk (#5058)

This commit is contained in:
Joe Haddad
2018-09-21 14:17:56 -04:00
committed by GitHub
parent 78f0a96133
commit e88809f489
4 changed files with 97 additions and 2 deletions

View File

@@ -0,0 +1,57 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
class InlineChunkHtmlPlugin {
constructor(htmlWebpackPlugin, tests) {
this.htmlWebpackPlugin = htmlWebpackPlugin;
this.tests = tests;
}
getInlinedTag(publicPath, assets, tag) {
if (tag.tagName !== 'script' || !(tag.attributes && tag.attributes.src)) {
return tag;
}
const scriptName = tag.attributes.src.replace(publicPath, '');
if (!this.tests.some(test => scriptName.match(test))) {
return tag;
}
const asset = assets[scriptName];
if (asset == null) {
return tag;
}
return { tagName: 'script', innerHTML: asset.source(), closeTag: true };
}
apply(compiler) {
let publicPath = compiler.options.output.publicPath;
if (!publicPath.endsWith('/')) {
publicPath += '/';
}
compiler.hooks.compilation.tap('InlineChunkHtmlPlugin', compilation => {
const tagFunction = tag =>
this.getInlinedTag(publicPath, compilation.assets, tag);
const hooks = this.htmlWebpackPlugin.getHooks(compilation);
hooks.alterAssetTagGroups.tap('InlineChunkHtmlPlugin', assets => {
assets.headTags = assets.headTags.map(tagFunction);
assets.bodyTags = assets.bodyTags.map(tagFunction);
});
hooks.afterEmit.tap('InlineChunkHtmlPlugin', () => {
Object.keys(compilation.assets).forEach(assetName => {
if (this.tests.some(test => assetName.match(test))) {
delete compilation.assets[assetName];
}
});
});
});
}
}
module.exports = InlineChunkHtmlPlugin;

View File

@@ -18,14 +18,14 @@ If you dont use Create React App, or if you [ejected](https://github.com/face
There is no single entry point. You can only import individual top-level modules. There is no single entry point. You can only import individual top-level modules.
#### `new InterpolateHtmlPlugin(replacements: {[key:string]: string})` #### `new InterpolateHtmlPlugin(htmlWebpackPlugin: HtmlWebpackPlugin, replacements: {[key:string]: string})`
This Webpack plugin lets us interpolate custom variables into `index.html`.<br> This Webpack plugin lets us interpolate custom variables into `index.html`.<br>
It works in tandem with [HtmlWebpackPlugin](https://github.com/ampedandwired/html-webpack-plugin) 2.x via its [events](https://github.com/ampedandwired/html-webpack-plugin#events). It works in tandem with [HtmlWebpackPlugin](https://github.com/ampedandwired/html-webpack-plugin) 2.x via its [events](https://github.com/ampedandwired/html-webpack-plugin#events).
```js ```js
var path = require('path'); var path = require('path');
var HtmlWebpackPlugin = require('html-dev-plugin'); var HtmlWebpackPlugin = require('html-webpack-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
// Webpack config // Webpack config
@@ -56,6 +56,39 @@ module.exports = {
}; };
``` ```
#### `new InlineChunkHtmlPlugin(htmlWebpackPlugin: HtmlWebpackPlugin, tests: Regex[])`
This Webpack plugin inlines script chunks into `index.html`.<br>
It works in tandem with [HtmlWebpackPlugin](https://github.com/ampedandwired/html-webpack-plugin) 4.x.
```js
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
// Webpack config
var publicUrl = '/my-custom-url';
module.exports = {
output: {
// ...
publicPath: publicUrl + '/',
},
// ...
plugins: [
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: path.resolve('public/index.html'),
}),
// Inlines chunks with `runtime` in the name
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime/]),
// ...
],
// ...
};
```
#### `new ModuleScopePlugin(appSrc: string | string[], allowedFiles?: string[])` #### `new ModuleScopePlugin(appSrc: string | string[], allowedFiles?: string[])`
This Webpack plugin ensures that relative imports from app's source directories don't reach outside of it. This Webpack plugin ensures that relative imports from app's source directories don't reach outside of it.

View File

@@ -24,6 +24,7 @@
"getCSSModuleLocalIdent.js", "getCSSModuleLocalIdent.js",
"getProcessForPort.js", "getProcessForPort.js",
"ignoredFiles.js", "ignoredFiles.js",
"InlineChunkHtmlPlugin.js",
"inquirer.js", "inquirer.js",
"InterpolateHtmlPlugin.js", "InterpolateHtmlPlugin.js",
"launchEditor.js", "launchEditor.js",

View File

@@ -12,6 +12,7 @@ const autoprefixer = require('autoprefixer');
const path = require('path'); const path = require('path');
const webpack = require('webpack'); const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TerserPlugin = require('terser-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
@@ -433,6 +434,9 @@ module.exports = {
minifyURLs: true, minifyURLs: true,
}, },
}), }),
// Inlines the webpack runtime script. This script is too small to warrant
// a network request.
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime~.+[.]js/]),
// Makes some environment variables available in index.html. // Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.: // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> // <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">