{
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 = "video";
index.js
document.querySelector('#play').addEventListener('click',() => {
import('./video').then(result => {
console.log(result.default);
});
});
index.html
<button id="play">播放</button>
<link rel="prefetch" href="utils.js" as="script">
button.addEventListener('click', () => {
import(
`./utils.js`
/* webpackPrefetch: true */
/* webpackChunkName: "utils" */
).then(result => {
result.default.log('hello');
})
});
Low
$ npm install --save-dev webpackpreload-webpack-plugin
<link rel="preload" as="script" href="utils.js">
import(
`./video.js`
/* webpackPreload: true */
/* webpackChunkName: "video" */
)
webpackpreload-webpack-plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
class WebpackpreloadWebpackPlugin {
apply(compiler) {
compiler.hooks.compilation.tap('PreloadWebpackPlugin', (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTags.tap('PreloadWebpackPlugin', (htmlData) => {
const { publicPath, assetTags } = htmlData;
const { entrypoints, moduleGraph, chunkGraph } = compilation;
for (const entrypoint of entrypoints) {
const preloaded = entrypoint[1].getChildrenByOrders(moduleGraph, chunkGraph).preload; // is ChunkGroup[] | undefined
if (!preloaded) return;
const chunks = new Set();
for (const group of preloaded) {
for (const chunk of group.chunks) chunks.add(chunk);
}
const files = new Set()
for (const chunk of chunks) {
for (const file of chunk.files) files.add(file);
}
const links = [];
for (const file of files) {
links.push({
tagName: 'link',
attributes: {
rel: 'preload',
href: `${publicPath}${file}`
}
});
}
assetTags.styles.unshift(...links);
}
});
});
}
}
module.exports = WebpackpreloadWebpackPlugin;
plugins\ImportPlugin.js
class ImportPlugin {
apply(compiler) {
compiler.hooks.compilation.tap(
"ImportPlugin",
(compilation, { normalModuleFactory }) => {
normalModuleFactory.hooks.parser
.for("javascript/auto")
.tap("ImportPlugin", (parser) => {
parser.hooks.importCall.tap("ImportParserPlugin", expr => {
const { options } = parser.parseCommentOptions(expr.range);
console.log(options);
});
});
}
);
}
}
module.exports = ImportPlugin;
怎么配置单页应用?怎么配置多页应用?
minChunks
规则的模块抽取到单独的Chunk
中maxInitialRequests
配置项的要求minSize
的大小,如果小于minSize
则不分包,如果大于minSize
判断是否超过maxSize
,如果大于maxSize
则继续拆分成更小的包Chunk
时所需要加载的所有的分包数量,包括Initial Chunk
,但不包括Async Chunk
和runtimeChunk
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