webpack使用require.ensure将vue页面打包成独立的chunk文件,也可以将多个vue页面合并成一个chunk文件,以实现生产环境按需加载。
下面给出官网的require.ensure函数原型:
require.ensure(
dependencies: String[],
callback: function(require),
errorCallback: function(error),
chunkName: String
)
各个参数含义如下:
1、dependencies:依赖
这是一个字符串数组,通过这个参数,在所有的回调函数代码被执行前,我们可以将所有需要用到的模块进行声明。
2、callback:回调
当所有的依赖都加载完成后,webpack会执行这个回调函数。require 对象的一个实现会作为一个参数传递给这个回调函数。因此,我们可以进一步 require() 依赖和其它模块提供下一步的执行。
3、errorCallback:错误回调
4、chunkName:chunk名称
chunkName 是提供给这个特定的 require.ensure() 的 chunk 的名称。通过提供 require.ensure() 不同执行点相同的名称,我们可以保证所有的依赖都会一起放进相同的文件束(bundle)。
概念说完了,接下以来以vue文件为例论证
在src/pages目录下新建confirm.vue和example.vue
然后在路由文件router/index.js中引入
const confirm = r => require.ensure([], () => r(require('../pages/confirm.vue')), 'group-confirm');
const example = r => require.ensure([], () => r(require('../pages/example.vue')), 'group-example');
如果要在打包文件中显示chunkName,则需要修改webpack.prod.conf文件的chunkFilename,并且要设置 webpack.base.conf.js文件中的publicPath,单独打包出来的chunk是以publicPath为存储路径的,一般生产环境我们都会存放在cdn上,这时可以给出cdn完整的路径。
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
- chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
+ chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
},
打包生成的文件如下图所示:
require.ensure是webpack所独有的,可以被es6的import取代:
const confirm = () => import(/* webpackChunkName: "group-confirm" */ '../pages/confirm');
const example = () => import(/* webpackChunkName: "group-example" */ '../pages/example');
此时或许大家会有一个小小的疑问,require.ensure只能用在生产环境吗?webpack是怎么区分生产和测试环境呢?
答案就是配置文件webpack.prod.conf.js中配置的chunkFilename,它与路由中的 require.ensure相互应,实现js文件分割。如果在webpack.dev.conf.js中也进行相同的配置,则开发环境中也会生成相应的chunk文件。