讲讲代码分割
webpack可以完成两类代码分割:分离资源,实现缓存资源和并行加载资源
/按需分离
分离资源
- 分离第三方库(vendor)
将一些第三方库保留到与应用程序代码相独立的bundle
上,就可以使用浏览器的缓存 - 分离css
使用ExtractTextWebpackPlugin
来分离css,增强了样式的可缓存性,以及能并行加载样式文件,避免了页面的闪烁问题
按需分离
使用require.ensure([<fileurl>])
代码拆分 – CSS
一般情况下,我们会在webpack.config.js
中做如下配置
1 | module.exports = { |
然而上述的配置不能利用浏览器的异步和并行加载css的能力,这时候网页必须等待,直到整个javascript
包加载完
怎么办呢?
使用ExtractTextWebpackPlugin
,使用前必须先下载这个包
1 | npm i --save-dev extract-text-webpack-plugin |
这时webpack.config.js
作如下改变
1 | let ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'); |
这样之后就能为所有的css模块产生新的bundle,并单独插入到index.html中
官方文档
extract-text-webpack-plugin问题
代码拆分 –库(Libraries)
利用浏览器的缓存就可以使第三方库缓存而不必多次请求,所以将应用代码
和第三方代码
分离很有必要
假设我们使用了第三方的一个库–jquery.js,我们做如下配置
1 | module.exports = { |
这样子,jquery就会被打包到bundle.js
里面了,如果我们改动应用代码,这时候就会重新构建这个文件,浏览器就要重新加载惹。
多入口
我们为jquery添加一个单独的入口,vendor
来缓解
1 | var path = require('path'); |
这样就有了两个bundle,但是两个文件中都会有jquery
what!!!!
CommonsChunkPlugin出场惹
它从根本上允许我们从不同的bundle中提取所有的公共模块,并将它们加入公共bundle中
1 | var webpack = require('webpack'), |
隐式公共vendor chunk
将CommonsChunkPlugin配置为只接受vendor库
1 | var webpack = require('webpack'); |
Manifest文件
即使做了如上配置后,我们运行webpack的时候,vendor文件的hash也变了,即使我们分开了两者,所以我们还是没有好好利用浏览器的缓存
这是因为每次构建时候产生的webpack runtime
代码被提取到了公共模块中了,为了解决这个问题,将运行时候的代码提取到单独的manifest
文件中
1 | var webpack = require('webpack'); |
代码拆分 –require.ensure
语法:
1 | require.ensure(dependencies:String[],callback:fn(require),chunkName:String) |
坑点
1) 空数组为参数
以下代码保证了拆分点被创建,而且 a.js 被 webpack 分开打包。
1 | require.ensure([],require=>{ |
2) 依赖作为参数
1 | require.ensure(['./a.js'], function(require) { |
a.js
和 b.js
都被打包到一起,而且从主文件束中拆分出来。但只有 b.js
的内容被执行。a.js
的内容仅仅是可被使用,但并没有被输出。
想去执行 a.js
,我们需要异步
地引用它,如 require('./a.js')
,让它的 JavaScritp 被执行。