Unverified Commit e88809f4 authored by Joe Haddad's avatar Joe Haddad Committed by GitHub
Browse files

Inline the webpack runtime chunk (#5058)

parent 78f0a961
Showing with 97 additions and 2 deletions
+97 -2
/**
* 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;
...@@ -18,14 +18,14 @@ If you don’t use Create React App, or if you [ejected](https://github.com/face ...@@ -18,14 +18,14 @@ If you don’t 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 = { ...@@ -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.
......
...@@ -24,6 +24,7 @@ ...@@ -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",
......
...@@ -12,6 +12,7 @@ const autoprefixer = require('autoprefixer'); ...@@ -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 = { ...@@ -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">
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment