{
entry: {
page1: "./src/page1.js",
page2: "./src/page2.js"
}
}
https://static.zhufengpeixun.com/http_xie_yi_rfc2616_zhong_ying_wen_shuang_ban_1637749432228.zip
hello.js
module.exports = "hello";
index.js
document.querySelector('#clickBtn').addEventListener('click',() => {
import('./hello').then(result => {
console.log(result.default);
});
});
index.html
<button id="clickBtn">点我</button>
Low
$ npm install --save-dev @vue/preload-webpack-plugin
<link rel="preload" as="script" href="utils.js">
import(
`./utils.js`
/* webpackPreload: true */
/* webpackChunkName: "utils" */
)
<link rel="prefetch" href="utils.js" as="script">
button.addEventListener('click', () => {
import(
`./utils.js`
/* webpackPrefetch: true */
/* webpackChunkName: "utils" */
).then(result => {
result.default.log('hello');
})
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="prefetch" href="prefetch.js?k=1" as="script">
<link rel="prefetch" href="prefetch.js?k=2" as="script">
<link rel="prefetch" href="prefetch.js?k=3" as="script">
<link rel="prefetch" href="prefetch.js?k=4" as="script">
<link rel="prefetch" href="prefetch.js?k=5" as="script">
</head>
<body>
</body>
<link rel="preload" href="preload.js" as="script">
</html>
plugins\preload-webpack-plugin.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
/**
* 1.查找当前产出代码块有哪些异步代码块
* 2.针对每个异步代码块生成一个link标签
* 3.把生成的link标签插入到结果的HTML文件中
*/
class PreloadWebpackPlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
//<link href="title.js" rel="prefetch"></link><
compiler.hooks.compilation.tap('PreloadWebpackPlugin', (compilation) => {
//在准备生成资源标签之前执行
HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync(
'PreloadWebpackPlugin',
(htmlData, callback) => {
this.generateLinks(compilation, htmlData, callback);
}
);
});
compiler.hooks.compilation.tap('PreloadWebpackPlugin', (compilation) => {
//在准备生成资源标签之前执行
HtmlWebpackPlugin.getHooks(compilation).alterAssetTags.tap(
'PreloadWebpackPlugin',
(htmlData) => {
const { resourceHints } = this;
if (resourceHints) {
htmlData.assetTags.styles = [
...resourceHints,
...htmlData.assetTags.styles
]
}
return htmlData;
}
);
});
}
generateLinks(compilation, htmlData, callback) {
const { rel, include } = this.options;
//本次编译产出的代码块
let chunks = [...compilation.chunks];
//如果说包括的是异步的代码块
if (include === undefined || include === 'asyncChunks') {
//如果chunk.canBeInitial()为true,说明这是一个入口代码块 main.canBeInitial()
//过滤一下,只留下异步代码块
chunks = chunks.filter(chunk => !chunk.canBeInitial());
}
let allFiles = chunks.reduce((accumulated, chunk) => {
return accumulated.add(...chunk.files);
}, new Set());
const links = [];
for (const file of allFiles.values()) {
links.push({
tagName: 'link',
attributes: {
rel,//preload prefetch
href: file
}
});
}
this.resourceHints = links;
callback()
}
}
module.exports = PreloadWebpackPlugin;
怎么配置单页应用?怎么配置多页应用?
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AssetPlugin = require('./asset-plugin');
module.exports = {
mode: 'development',
devtool: false,
entry: {
page1: "./src/page1.js",
page2: "./src/page2.js",
page3: "./src/page3.js",
},
optimization: {
splitChunks: {
// 表示选择哪些 chunks 进行分割,可选值有:async,initial和all
chunks: 'all',
// 表示新分离出的chunk必须大于等于minSize,默认为30000,约30kb。
minSize: 0,//默认值是20000,生成的代码块的最小尺寸
// 表示一个模块至少应被minChunks个chunk所包含才能分割。默认为1。
minChunks: 1,
// 表示按需加载文件时,并行请求的最大数目。默认为5。
maxAsyncRequests: 3,
// 表示加载入口文件时,并行请求的最大数目。默认为3
maxInitialRequests: 5,
// 表示拆分出的chunk的名称连接符。默认为~。如chunk~vendors.js
automaticNameDelimiter: '~',
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/, //条件
priority: -10 ///优先级,一个chunk很可能满足多个缓存组,会被抽取到优先级高的缓存组中,为了能够让自定义缓存组有更高的优先级(默认0),默认缓存组的priority属性为负值.
},
default: {
minChunks: 2,////被多少模块共享,在分割之前模块的被引用次数
priority: -20
},
},
},
runtimeChunk: true
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
chunks: ["page1"],
filename: 'page1.html'
}),
new HtmlWebpackPlugin({
template: './src/index.html',
chunks: ["page2"],
filename: 'page2.html'
}),
new HtmlWebpackPlugin({
template: './src/index.html',
chunks: ["page3"],
filename: 'page3.html'
}),
new AssetPlugin()
]
}
plugins\webpack-assets-plugin.js
class WebpackAssetsPlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
//每当webpack开启一次新的编译 ,就会创建一个新的compilation
compiler.hooks.compilation.tap('WebpackAssetsPlugin', (compilation) => {
//每次根据chunk创建一个新的文件后会触发一次chunkAsset
compilation.hooks.chunkAsset.tap('WebpackAssetsPlugin', (chunk, filename) => {
console.log(chunk.id, filename);
});
});
}
}
module.exports = WebpackAssetsPlugin;
let module1 = require('./module1');
let module2 = require('./module2');
let $ = require('jquery');
console.log(module1,module2,$);
import( /* webpackChunkName: "asyncModule1" */ './asyncModule1');
let module1 = require('./module1');
let module2 = require('./module2');
let $ = require('jquery');
console.log(module1,module2,$);
let module1 = require('./module1');
let module3 = require('./module3');
let $ = require('jquery');
console.log(module1,module3,$);
module.exports = 'module1';
console.log("module2");
console.log("module3");
import _ from 'lodash';
console.log(_);
//入口代码块
page1.js
page2.js
page3.js
//异步加载代码块
src_asyncModule1_js.js
//defaultVendors缓存组对应的代码块
defaultVendors-node_modules_jquery_dist_jquery_js.js
defaultVendors-node_modules_lodash_lodash_js.js
//default代缓存组对应的代码块
default-src_module1_js.js
default-src_module2_js.js
let page1Chunk= {
name:'page1',
modules:['A','B','C','lodash']
}
let page2Chunk = {
name:'page2',
module:['C','D','E','lodash']
}
let cacheGroups= {
vendor: {
test: /lodash/,
},
default: {
minChunks: 2,
}
};
let vendorChunk = {
name:`vendor~node_modules_lodash_js`,
modules:['lodash']
}
let defaultChunk = {
name:`default~page1~page2`,
modules:['C']
}
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AssetPlugin = require('./asset-plugin');
module.exports = {
mode: 'development',
devtool: false,
+ entry: './src/index.js',
optimization: {
splitChunks: {
// 表示选择哪些 chunks 进行分割,可选值有:async,initial和all
chunks: 'all',
// 表示新分离出的chunk必须大于等于minSize,默认为30000,约30kb。
minSize: 0,//默认值是20000,生成的代码块的最小尺寸
// 表示一个模块至少应被minChunks个chunk所包含才能分割。默认为1。
minChunks: 1,
// 表示按需加载文件时,并行请求的最大数目。默认为5。
maxAsyncRequests: 3,
// 表示加载入口文件时,并行请求的最大数目。默认为3
maxInitialRequests: 5,
// 表示拆分出的chunk的名称连接符。默认为~。如chunk~vendors.js
automaticNameDelimiter: '~',
+ cacheGroups: {
+ defaultVendors: false,
+ default: false,
+ common: {
+ minChunks: 1,
+ reuseExistingChunk: false
+ }
+ }
},
+ runtimeChunk: false
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
})
new AssetPlugin()
]
}
//reuseExistingChunk: false
main main.js
common-src_index_js common-src_index_js.js
//reuseExistingChunk: true
main main.js