mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-04-29 18:05:47 +08:00
Inline the webpack runtime chunk (#5058)
This commit is contained in:
57
packages/react-dev-utils/InlineChunkHtmlPlugin.js
vendored
Normal file
57
packages/react-dev-utils/InlineChunkHtmlPlugin.js
vendored
Normal 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;
|
||||||
@@ -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 = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `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 @@
|
|||||||
"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');
|
|||||||
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">
|
||||||
|
|||||||
Reference in New Issue
Block a user