代码分离是webpack最引人注目的特性之一,能够把不同的代码分离到不同的 bundle 中,所谓 bundle,就是我们打包分离出来的文件,然后我们把这些文件按需加载或者并行加载,代码分离可以用于获取更小的 bundle,以及控制资源加载的优先级,如果使用合理,会极大的影响加载时间。
问题:如果有多个入口,那么这些多个入口共享的文件会分别在每个包里边去重复打包
迄今为止最简单直观的分离代码的方式,不过,这种方式手动配置较多,并有一些隐患
在 src 目录下创建 another-module.js 文件:
import _ from 'lodash'
console.log(_.join(['Another', 'module', 'loaded!'], ' '))
更改 webpack 配置文件:
在index.js文件内也引用
import _ from 'lodash'
console.log(_.join(['index', 'module', 'loaded!'], ' '))
执行 npx webpack 进行打包,生成 dist 文件夹
控制台打印:
第一种:
修改webpack配置:
// 入口文件
entry: {
index: {
import: './src/index.js',
// 把共享的文件定义出来
dependOn: 'shared'
},
another: {
import: './src/another-module.js',
dependOn: 'shared'
},
// 当上面两个模块里边有lodash这个模块的时候,就会把它抽离出来,并给它取名叫shared
shared: 'lodash'
},
此时 npx webpack 打包可以看到
第二种:使用 split-chunks-Plugin 插件
修改 webpack 配置文件:
// 入口文件
entry: {
index: './src/index.js',
another: './src/another-module.js'
},
// 优化配置
optimization: {
splitChunks: {
chunks: 'all'
}
}
第一种(推荐):使用符合 ECMAScript提案的 import() 语法来实现动态导入
更改webpack 配置:
// 入口文件
entry: {
index: './src/index.js',
another: './src/another-module.js'
},
在 src 文件夹内新建 async-module.js 文件
function getComponent() {
return import('lodash')
.then(({default: _}) => {
const element = document.createElement('div')
element.innerHTML = _.join(['hello', 'webpack'], ' ')
return element
})
}
getComponent().then((element) => {
document.body.appendChild(element)
})
在 index.js 中引入
import './async-module.js'
console.log(_.join(['index', 'module', 'loaded!'], ' '))
第二种:使用 webpack 特定的 require.ensure
懒加载
在 src 文件夹内新建 math.js文件
export const add = (x, y) => {
return x + y
}
export const minus = (x, y) => {
return x - y
}
在index.js中引入
const button = document.createElement('button')
button.textContent = '点击执行加法运算'
button.addEventListener('click', () => {
// /* webpackChunkName: 'math'*/表示打包好的文件名
import(/* webpackChunkName: 'math'*/'./math.js').then(({add}) => {
console.log(add(4, 5))
})
})
document.body.appendChild(button)
此时页面新增按钮,当点击这个按钮的时候,才会调这个模块,控制台打印 9
预获取/预加载模块
在声明 import 时,使用下面这些内置指令,可以让webpack输出“reaource(资源提示)”,来告知浏览器:
首次进来加载了,但没有执行里面的代码,当点击按钮的时候,才会执行里面的代码;意义在于当首页面的内容都加载完毕,在网络空闲的时候,再去加载打包好的 math.bundle.js,比懒加载要好
和懒加载的效果类似