IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Webpack DllPlugin打包小技巧

    BccSafe发表于 2016-12-11 17:56:58
    love 0

    前端项目构建过程中,为了提高构建效率,用上cache,往往会将第三方库和自己的业务逻辑代码分开打包,在Webpack里有两个插件可以完成这项任务,CommonsChunk和DLL & DllReference

    CommonsChunk

    可以将相同的模块提取出来单独打包,进而减小 rebuild 时的性能消耗,但是每次构建时都需要执行一次,显然很浪费时间

    DLL & DllReference

    相比于前者,通过前置这些依赖包的构建,来提高真正的 build 和 rebuild 的构建效率。也就是说只要第三方库没有变化,之后的每次build都只需要去打包自己的业务代码。这个思路应该来源于Windows的动态链接库 (DLL)

    如何使用DLL & DllReference在这里不再敖述,网上资料还是比较多的,可以参考 https://segmentfault.com/a/11...

    出现的问题

    使用DLL & DllReference后,第三方库的确前置构建了,但是如何让打包出来的bundle文件在index.html中引用呢?如果output.fileName写死名字,在index.html中也写死,就没有了强缓存,如果ouput.fileName=[name].[hash].js,就得找到一个往html里添加js的办法

    assets-webpack-plugin

    When working with Webpack you might want to generate your bundles with a generated hash in them (for cache busting).

    This plug-in outputs a json file with the paths of the generated assets so you can find them from somewhere else.

    有了这个插件,看起来就行得通了,在打包第三库时使用assets-webpack-plugin将bundle的文件名输出,保存成json,在打包业务代码时配合html-webpack-plugin插件,将bundle添加到index.html中

    webpack.dll.config.js

    const webpack = require('webpack');
    const AssetsPlugin = require('assets-webpack-plugin');
    
    module.exports = {
        entry: {
            bundle: [
                'history',
                'react', 
                'react-router', 
                'react-dom', 
                'react-redux', 
                'react-router', 
                'react-router-redux', 
                'redux',
                'redux-thunk'
                ]
        },
        output: {
            path: '/',
            filename: '[name].[hash].js',
            library: '[name]_library'
        },
        plugins: [
            new webpack.DllPlugin({
                path: '/',      
                name: '[name]_library'
            }),
            new AssetsPlugin({
                filename: 'bundle-config.json', 
                path: '/'
            }),
        ]
    };

    webpack.config.js

    const webpack = require('webpack');
    const bundleConfig = require("/bundle-config.json");
    module.exports = {
        entry: {
            app: ['./app.tsx']
        },
        output: {
            path: '/',
            publicPath: '',
            filename: '[name]-[hash].js',
            chunkFilename: '[name]-[chunkhash].js'
        },
        plugins: [
            new HtmlwebpackPlugin({
                filename: 'index.html',
                chunks: ['app'],
                template: 'app.html',
                bundleName: bundleConfig.bundle.js,
                minify: __DEV__ ? false : {
                    collapseWhitespace: true,
                    collapseInlineTagWhitespace: true,
                    removeRedundantAttributes: true,
                    removeEmptyAttributes: true,
                    removeScriptTypeAttributes: true,
                    removeStyleLinkTypeAttributes: true,
                    removeComments: true
                }
            }),
            new webpack.DllReferencePlugin({
                context: '.',
                manifest: require('/bundle-manifest.json') 
            })
        ]
    };

    app.html里需要用到这样的模版 <%= htmlWebpackPlugin.options.bundleName %>

    到这里,整个构建过程就比较舒服了,不重复打第三方库的包,也用上了强缓存

    更详细的代码可以参考我搭的这个脚手架 https://github.com/bccsafe/Re...

    参考资料

    • https://segmentfault.com/a/11...

    • http://engineering.invisionap...

    • https://github.com/ampedandwi...

    • https://github.com/kossnocorp...



沪ICP备19023445号-2号
友情链接