代码分割(Code Splitting)是 webpack 最引人注目、非常有竞争力的功能之一,此功能使您可以将代码分成多个捆绑包,然后可以按需或并行加载,提升资源下载速度。
概念理解
假如我们的业务代码引入了第三方库 lodash.js,那么就有两种打包方式
- 第一种方式,是只打包成一个 mian.js(2MB),那么打包文件会很大,打包时间会很长,重新访问页面又需要加载 2MB 的内容。
- 第二种方式,把 main.js 拆成 mian.js(1MB) 和 lodash.js(1MB) 两个文件,此时用户加载页面的时候就只需要加载 1MB 的 main.js 文件(lodash.js 会被浏览器缓存。)
很明显,第一种方式如果修改了业务代码又需要把 lodash 打包进去,打包文件又大打包时间又长,用户加载页面浏览器需要一次性加载一个 2MB 的打包后的文件。第二种方式如果只改动了业务代码只需要重新打包业务代码即可,用户加载页面浏览器只下载 main.js 即可。
这就是 Code Splitting,有了它我们可以把代码进行拆分,让我们的代码执行的性能更高一些,让用户体验更好一些。
webpack 和 Code Splitting 的关系
Code Splitting 本质上和 webpack 其实没有任何关系的,在没有 webpack 之前我们通过自己对代码进行拆分,也可以有效的提升我们项目的性能。现在我们说 Code Splitting 已经和 webpack 有所绑定了呢,这是因为 webpack 有一些插件可以非常容易的帮助我们实现 Code Splitting 这样的功能,在 webpack4 里面,有一个插件叫 splitChunksPlugin,这个插件直接就和 webpack 做了捆绑,我们都不用安装直接就可以使用,所以用 webpack 来做 Code Splitting 这样的事情会变的非常简单。
通过 webpack 可以智能的自动帮我们做 Code Splitting 这件事情,那么 webapck 是怎么做的呢?
使用
有如下代码:
// 类库import _ from 'lodash'// 业务代码console.log(1)console.log(2)
webpack.config.js 增加一个配置项:
optimization: { splitChunksPlugin: { chunks: 'all' }}
通过这样简单的配置,webapck 就会自动的帮我们业务代码和类库代码分别打包成一个 chunks(也就是一个打包后的文件)。这就是为什么说 webpack 中的 Code Splitting 是非常有竞争力的功能。
当然 webpack 里面的 Code Splitting 不仅仅可以通过这样的一个配置项帮我们完成,还可以通过另外一种方式 Code Splitting,前面我的代码是使用同步的方式,下面看一段异步的代码:
function getComponent() { return import('lodash').then(({ default: _ }) => { const element = document.createElement('div') element.innerHTML = _.join(['Bing', 'Zhang'], '-') return element })}getComponent().then(element => { document.body.appendChild = element})
这段代码会异步加载一个 loadash,当加载完后会创建一个 Div 标签,并且调用 lodash 的 join 方法拼接了一个字符串并返回了 element。返回的 element 其实也是一个 Promise,我们把他挂载到了 Body 节点上。
如果打包时候提示如下错误,意思是说这是一种实验性质的语法,我们需要使用一个插件来让 webpack 来做一下转换(weboack 4.41.2 不会报错)。
这是 babel 的一个插件: babel-plugin-dynamic-import-webpack,然后在 .babelrc 中配置这个插件:
{ plugins: ['babel-plugin-dynamic-import-webpack']}
这时候再打包 webpack 就会把这种异步加载的模块单独打包成一个文件,这里就会成功把 lodash 和 业务代码打包成功两个文件。
总结
Code Splitting 和 webpack 无关。webpack 中实现 Code Splitting 有两种方式同步代码:只需要在 webapck 配置中做 optimization 配置异步代码(import):无需做任何配置会自动做代码分割放置到到单独文件中。
作者简介:做工程不做码农(微信公众号同名),Web前端工程师,7年开发经验,坐标杭州,聚焦大前端技术和程序员成长的公众号。