webpack 代码分离

代码分离是什么

代码分离指将代码分离到不同的 bundle 中。

有什么作用

代码分离后就可以按需加载或并行加载这些文件。

常用方法

  1. 入口起点
  2. 使用 SplitChunksPlugin 去重和分离 chunk
  3. 动态导入(也叫 懒加载、延迟加载)

1、入口起点

在 webpack.config.js 中配置多个 entry 入口,能够分离代码,进而产生多个 bundle。

缺点: 多个 entry 引用的重复文件会被重复打包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// webpack.config.js
const path = require('path');

module.exports = {
mode: 'development',
entry: {//配置多个 entry 入口
index: './src/index.js',
another: './src/another-module.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};

2、使用 SplitChunksPlugin

SplitChunkksPlugin 可以将多个 entry 入口中的公共模块提取出来,达到去重公共模块的效果。

webpack 的 optimization.splitChunks 选项默认使用 SplitChunkPlugin 插件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//webpack.config.js
const path = require("path");

module.exports = {
mode: "development",
entry: {
index: "./src/js/index.js",
other: "./src/js/other.js",
},
output: {
filename: "./js/[name].[contenthash:5].js",
path: path.resolve(__dirname, "dist"),
},
optimization: {
splitChunks: {
chunks: "all",
},
},
};

3、动态导入

动态导入(也叫 懒加载 或 延迟加载),这个加载方式建立在代码分离的基础上,使得一些 trunk 可以在浏览器空闲 或 业务逻辑需要时才被加载。

懒加载的作用是 为了提高应用的初始加载速度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
entry: {
main: "./src/js/index.js",
},
output: {
filename: "[name].[contenthash:10].js",
},
plugins: [new HtmlWebpackPlugin()],
mode: "development",
};
1
2
3
4
5
6
7
8
9
10
//print.js
console.log("The print.js module has loaded! See the network tab in dev tools...");

export default () => {
console.log('Button Clicked: Here\'s "some text"!');
};

export function add() {
console.log("hello add");
}

下面代码在 onclick 事件中通过 import 语句动态加载模块,从而提高首屏加载速度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//index.js
import _ from "lodash";

function component() {
var element = document.createElement("div");
var button = document.createElement("button");
var br = document.createElement("br");

button.innerHTML = "Click me and look at the console!";
element.appendChild(br);
element.appendChild(button);

//在 onclick 事件中通过 import 语句动态加载模块,从而提高首屏加载速度
button.onclick = (e) =>
import(/* webpackChunkName: "print" */ "./print").then((module) => {
console.log(module); //{add:f add(), default: ()=>{...},...}

var print = module.default;

print();
});

return element;
}

document.body.appendChild(component());