| 什么是代码分离
代码分离是webpack最引人注目的特性之一,
代码分离能够把代码分离到不同的bundle中,
然后再按需加载或并行加载。
代码分离可以用于获取更小的bundle
可以控制资源加载优先级,进而影响加载时间。
常用的代码分离方法
- 配置入口起点entry
- 防止重复的分离方法
- 动态导入
| 修改入口起点
module.exports = {
- // entry: './src/index.js'
+ entry: {
+ index: './src/index.js',
+ another: './src/another.js' // 其他入口文件
},
output: {
- // filename: 'bundle.js',
+ filename: '[name].bundle.js', // [name]会匹配entry的键
},
};
打包后结果
缺陷:
如果在两个文件中共享同一个库,比如lodash
那么两个文件都会把lodash压缩进去,这样就重复了
| 防止重复
module.exports = {
- // entry: {
- // index: './src/index.js',
- // another: './src/another.js' // 其他入口文件
- // },
+ entry: {
+ index: {
+ import: './src/index.js',
+ dependOn: 'shared', // 该文件共享shared指定模块
+ },
+ another: {
+ import: './src/another.js',
+ dependOn: 'shared', // 该文件共享shared指定模块
+ },
+ shared: 'lodash', // 共享lodash库
+ },
output: {
filename: '[name].bundle.js', // [name]会匹配entry的键
},
};
执行npx webpack后 会生成三个文件,共享的模块会被单独抽离出来
可以看到有效减小了包大小
自动分割代码
module.exports = {
entry: {
index: './src/index.js',
another: './src/another.js' // 其他入口文件
},
output: {
filename: '[name].bundle.js', // [name]会匹配entry的键
},
optimization: {
minimizer: [new CssMinimizerWebpackPlugin()],
+ splitChunks: {
+ chunks: 'all',
+ },
},
};
执行结果
| 动态导入
动态导入有两种
- webpack推荐的
import()语法来实现动态导入 - webpack特定的
require.ensure
1.创建一个async-module.js文件
function getComponent() {
// 动态加载
return import('lodash').then(({ default: _ }) => {
const ele = document.createElement('div');
ele.innerHTML = _.join(['Hello', 'webpack'], ' ');
return ele;
});
}
getComponent().then(ele => {
document.body.appendChild(ele);
});
2.index.js中引入
import './async-module.js'
3.执行打包后lodash同样被抽离出来了
如果需要与静态打包一起使用需要把代码自动分割打开
optimization: {
splitChunks: {
chunks: 'all',
},
},
应用一 懒加载
懒加载也叫按需加载,当需要使用时才会加载,这样一来就提升了应用初始加载速度,减轻总体体积。
1.懒加载一个名为math的模块
/* webpackChunkName: 'math' */叫魔法注释,这里的作用是给math命名
const btn = document.createElement('button');
btn.textContent = '执行加法运算';
btn.addEventListener('click', () => {
import(/* webpackChunkName: 'math' */ './math.js').then(({ add }) => {
console.log(add(1, 2));
});
});
document.body.appendChild(btn);
2.执行npx webpack后
3.首次加载并没有加载math模块
当我们点击按钮时才会加载
应用二 预获取/预加载
webpack4.6+版本已经增加了预获取与预加载的支持。
在声明import时使用以下内置指令可以告知浏览器执行:
prefetch:预获取preload:预加载
预获取
1.在魔法注释中加入webpackPrefetch: true
const btn = document.createElement('button');
btn.textContent = '执行加法运算';
btn.addEventListener('click', () => {
import(/* webpackChunkName: 'math',webpackPrefetch: true */ './math.js').then(({ add }) => {
console.log(add(1, 2));
});
});
document.body.appendChild(btn);
2.可以看到首次加载时已经被预获取出来了
在head标签里可以看到math被进行预获取处理了
预加载
1.在魔法注释中加入webpackPreload: true
const btn = document.createElement('button');
btn.textContent = '执行加法运算';
btn.addEventListener('click', () => {
import(/* webpackChunkName: 'math',webpackPreload: true */ './math.js').then(({ add }) => {
console.log(add(1, 2));
});
});
document.body.appendChild(btn);
2.效果与懒加载一样
<link rel="preload" as="script" href="math.bundle.js">
不当地使用wepbackPreload会损害性能,所以使用的时候要小心