webpack代码分割

大多数时候,使用webpack将所有的代码打包到一起是不合适的,如:我们希望将样式单独打包使用link标签引用、很多首页不需要的资源按需加载、缓存不常变动的代码。

1、按需加载拆分

require.ensure()是一种使用 CommonJS 的形式来异步加载模块的策略。语法如下:

require.ensure(dependencies: String[], callback: function(require), chunkName: String)

第一个参数:依赖的模块

第二个参数:依赖加载成功之后的回调函数。require 对象的一个实现会作为一个参数传递给这个回调函数。因此,我们可以进一步 require() 依赖和其它模块提供下一步的执行。

第三个参数:chunk名称

  a、第一个参数为空数组,requireEnsure.vue会被webpack分开打包

require.ensure([], (require) => {
  require('./components/requireEnsure.vue')
}, 'requireEnsure')

  b、pageA.js和requireEnsure1.js会被打包到一起,而且从主文件束中拆分出来。但只有 requireEnsure1.js 的内容被执行。pageA.js 的内容仅仅是可被使用,但并没有被输出。想去执行 pageA.js,我们需要异步地引用它,如 require('./pageA.js'),让它的 JavaScritp 被执行。

require.ensure(['./components/pageA.js'], (require) => {
  require('./components/requireEnsure1.js')
}, 'requireEnsure1')
 c、a.js和b.js都依赖c.js,c模块被打包了两次
require.ensure(['./c'], function(require){
    let a = require('./a');
    console.log(a)
});

require.ensure(['./c'], function(require){
    let b = require('./b');
    console.log(b)
});

  设置第三个参数chunkName,就可以避免c模块被打包为两次的情况了

require.ensure(['./c'], function(require){
    let a = require('./a');
    console.log(a)
}, 'd');

require.ensure(['./c'], function(require){
    let b = require('./b');
    console.log(b)
}, 'd');

ok,这样以上两个 require.ensure 拆出来的包就合并为同一个了。

require.ensure中回调函数require的文件会被单独打包,打包后的结果文件webpack会自动给这些文件命名,但这样不是很好识别,有时候我们想自己给打包后的文件取名,修改webpack的配置文件如下:

module.exports = {
  entry: './index.js',
  output: {
    path: __dirname + '/dist/',
    filename: '[name].js',
    publicPath: __dirname + '/dist/', // 文件路径
    chunkFilename: '[name].js' // 文件名称
  }
}

ok,这样,打包后的文件就是我们自己取的名称了

2、拆分框架代码和业务代码

      在我们开发的时候,可能会依赖一些第三方库,第三方库的代码一般比较稳定,不需要经常变动。因此我们想的是将业务代码和框架代码分开打包,这样可以充分利用浏览器缓存,不需要每次都把框架代码加载一遍。

      webpack的配置如下:

module.exports = {
    entry: {
        main: './index.js',
        vendor: ['react', 'react-dom']
    }
    // 其他配置
}

    这样配置后,打包后就会得到main.js和vendor.js这两个文件,但是,在main.js中还是会包含react和react-dom中的代码,这是因为在index.js中引用了react和react-dom,webpack打包的时候会从入口文件开始查找依赖,并用loader来处理,所以,react和react-dom自然被打包了进去。如何才能实现不重复打包框架代码呢?这里我们需要用到webpack的一个插件CommonsChunkPlugin

使用CommonsChunkPlugin

      CommonsChunkPlugin插件的主要作用是将多个打包结果中公共的部分抽取出来。      

let webpack = require('webpack');

module.exports = {
    entry: {
        main: 'index.js',
        vendor: ['react', 'react-dom']
    },
    //...

    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor' // 指定一个希望作为公共包的入口
        })
    ]
}

      再进行打包发现main.js中不存在react的代码了。

3、css代码拆分

extract-text-webpack-plugin

安装extract-text-webpack-plugin

npm i --save-dev extract-text-webpack-plugin

在webpack配置文件中加入该插件:

var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = function () {
    return {
        entry: './index.js',
        output: {
            path: './build',
            filename: 'bundle.js'
        },
        module: {
            loaders: [{
                test: /\.css$/,
                exclude: /node_modules/,
                // 在 loader 中使用该插件
                loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
            }]
        },
        plugins: [
            // 将其添加在插件中
            new ExtractTextPlugin({ filename: 'bundle.css', disable: false, allChunks: true })
        ]
    }
}

 

posted @ 2017-10-11 14:48  RunningAndRunning  阅读(1842)  评论(0编辑  收藏  举报