美文网首页
webpack优化-代码拆分

webpack优化-代码拆分

作者: 大饼脸me | 来源:发表于2017-07-04 15:20 被阅读380次
    一、分离第三方库(vendor)

    把第三方代码和应用本身的代码一起打包是非常低效的。
    因为浏览器会根据缓存头来缓存资源文件,如果文件没有被改变,文件将会被缓存从而不用去再次请求 cdn。
    为了利用这一特性,我们希望不管应用本身的代码如何改变,vendor 文件的 hash 始终恒定不变。

    用法:

    var webpack = require('webpack');
    var path = require('path');
    
    module.exports = function(env) {
        return {
            entry: {
                main: './index.js',
                vendor: 'moment'
            },
            output: {
                filename: '[chunkhash].[name].js',
                path: path.resolve(__dirname, 'dist')
            },
            plugins: [
                new webpack.optimize.CommonsChunkPlugin({
                    name: 'vendor' // 指定公共 bundle 的名字。
                })
            ]
        }
    }
    

    为第三方库moment添加一个单独的入口vendor,在不使用CommonsChunkPlugin的情况下,webpack运行后会生成两个bundle,并且两个bundle中都会有moment的代码。
    CommonsChunkPlugin允许我们从不同的 bundle 中提取所有的公共模块,并且将他们加入公共 bundle 中。如果公共 bundle 不存在,那么它将会创建一个出来。
    利用这个特性,我们指定公共bundle的名字与moment的bundle文件一样,从而让CommonsChunkPlugin提取的公共模块覆盖moment的bundle文件,达到分离第三方库的效果。

    至此,我们已经成功的将第三方代码提取到了独立的bundle,但上文提到的浏览器缓存机制我们还是无法用上,因为 vendor 的 hash 在每次构建中都会改变,浏览器也必须重新加载文件。

    解决方案:

    var webpack = require('webpack');
    var path = require('path');
    
    module.exports = function(env) {
        return {
            entry: {
                main: './index.js',
                vendor: 'moment'
            },
            output: {
                filename: '[chunkhash].[name].js',
                path: path.resolve(__dirname, 'dist')
            },
            plugins: [
                new webpack.optimize.CommonsChunkPlugin({
                    names: ['vendor', 'manifest'] // 指定公共 bundle 的名字。
                })
            ]
        }
    };
    

    最终会生成多一个mainfest bundle
    更多介绍见 webpack优化-缓存

    二、分离CSS

    1、导入 CSS

    import 'bootstrap/dist/css/bootstrap.css';
    

    2、使用 css-loader

    module.exports = {
        module: {
            rules: [{
                test: /\.css$/,
                use: 'css-loader'
            }]
        }
    }
    

    结果,CSS和您的JavaScript打包在一起。
    这有个缺点,您将无法利用浏览器的异步和并行加载CSS的能力。这样,您的网页必须等待,直到您的整个JavaScript 包下载完成,然后重绘网页。

    3、使用 ExtractTextWebpackPlugin
    这个插件要自己安装

    module.exports = {
        module: {
             rules: [{
                 test: /\.css$/,
    -            use: 'css-loader'
    +            use: ExtractTextPlugin.extract({
    +                use: 'css-loader'
    +            })
             }]
         },
    +    plugins: [
    +        new ExtractTextPlugin('styles.css'),
    +    ]
    }
    
    三、按需分离

    虽然前面几类资源分离,需要用户预先在配置中指定分离模块,但也可以在应用程序代码中创建动态分离模块。
    这可以用于更细粒度的代码块,例如,根据我们的应用程序路由,或根据用户行为预测。这可以使用户按照实际需要加载非必要资源。

    四、使用 require.ensure() 分离代码
    require.ensure(dependencies: String[], callback: function(require), chunkName: String)
    

    两种情况:

    // 空数组作为参数
    require.ensure([], function(require){
        require('./a.js');
    });
    

    a.js会被打包到独立的bundle,例如entry打包输出为bundle.js,a.js会被打包为0.bundle.js

    //依赖作为参数
    require.ensure(['./a.js'], function(require) {
        require('./b.js');
    });
    

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

    相关文章

      网友评论

          本文标题:webpack优化-代码拆分

          本文链接:https://www.haomeiwen.com/subject/sjxxhxtx.html