webpack优化-速度优化-Dll

5 篇文章 0 订阅

一、DLLPlugin的使用

   1、背景

         对于vue项目而言,不可避免的会使用一些第三方的库,这些库本身并不会运行,我们也不会修改这些库的代码,但是每当我们修改了业务代码之后,这些库也会被重新打包,极大的浪费了时间,这时我们就需要使用工具预先把静态资源提前打包,以后修改源文件再打包时就不会打包这些静态资源文件了。而webpack在打包的时候,对于一些不经常更新的第三方库,比如 d3lodash,我们希望能和自己的代码分离开,也就是单独打包。

   2、简介

        DLLPlugin 和 DLLReferencePlugin 用某种方法实现了拆分 bundles,同时还大大提升了构建的速度。

  DllPlugin 

               这个插件是在一个额外的独立的 webpack 设置中创建一个只有 dll 的 bundle(dll-only-bundle)。 这个插件会生成一个名             为 manifest.json 的文件,这个文件是用来让 DLLReferencePlugin 映射到相关的依赖上去的。

       context (optional): manifest 文件中请求的上下文(context)(默认值为 webpack 的上下文(context))

       name: 暴露出的 DLL 的函数名 (TemplatePaths[hash] & [name] )

       path: manifest json 文件的绝对路径 (输出文件)

              在给定的 path 路径下创建一个名为 manifest.json 的文件。 这个文件包含了从 require 和 import 的request到模            块        id 的映射。 DLLReferencePlugin 也会用到这个文件。

new webpack.DllPlugin({
   path: path.resolve(__dirname, '../libs/[name]-mainfest.json'),
   name: '[name]_library',
   context: __dirname, // 执行的上下文环境,对之后DllReferencePlugin有用
}),

  llReferencePlugin 

               这个插件是在 webpack 主配置文件中设置的, 这个插件把只有 dll 的 bundle(们)(dll-only-bundle(s)) 引用到需要的预编译的依赖。

  • context: (绝对路径) manifest (或者是内容属性)中请求的上下文
  • manifest: 包含 content 和 name 的对象,或者在编译时(compilation)的一个用于加载的 JSON manifest 绝对路径
  • content (optional): 请求到模块 id 的映射 (默认值为 manifest.content)
  • name (optional): dll 暴露的地方的名称 (默认值为 manifest.name) (可参考 externals)
  • scope (optional): dll 中内容的前缀
  • sourceType (optional): dll 是如何暴露的 (libraryTarget)
new webpack.DllReferencePlugin({
    context: __dirname,
    manifest: require("../libs/libs-mainfest.json") // 指向生成的manifest.json
}),

通过引用 dll 的 manifest 文件来把依赖的名称映射到模块的 id 上,之后再在需要的时候通过内置的 __webpack_require__ 函数来 require 他们。

   3、实现

          1⃣️.创建webpack.dll.conf.js配置文件            

           

var path = require('path')
var webpack = require('webpack')
var AssetsPlugin = require('assets-webpack-plugin')
var CleanWebpackPlugin = require('clean-webpack-plugin')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var env = config.build.env

module.exports = {
    entry: {
        libs: [
            'vue-router',
            'vuex',
            'd3',
            'jointjs',
            'element-ui',
            'echarts',
            'moment',
            'pusher-js',
            'lodash'
        ],
    },
    output: {
        path: path.resolve(__dirname, '../libs'),
        filename: '[name].[chunkhash:7].js',
        library: '[name]_library',
    },
    plugins: [
        new webpack.DefinePlugin({
            'process.env': env,
        }),
        new webpack.DllPlugin({
            path: path.resolve(__dirname, '../libs/[name]-mainfest.json'),
            name: '[name]_library',
            context: __dirname, // 执行的上下文环境,对之后DllReferencePlugin有用
        }),
        // 将包或包中的文本提取到单独的文件中
        new ExtractTextPlugin('[name].[contenthash:7].css'),
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false,
            },
        }),
        // 使用Webpack时,您可能希望生成包含生成哈希的包(用于缓存清除)。
        // 此插件输出一个json文件,其中包含生成的资源的路径,以便您可以从其他位置找到它们
        new AssetsPlugin({
            filename: 'bundle-config.json',
            path: './libs',
        }),
       // 用于在构建之前删除/清除构建文件夹
       // verbose: true,将日志写入控制台
        new CleanWebpackPlugin(['libs'], {
            root: path.join(__dirname, '../'), // 绝对路径
            verbose: true,
            dry: false,
        }),
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
            },
        ],
    },
}

           2⃣️、创建build-dll.js文件

var path = require("path")
var webpack = require("webpack")
var dllConfig = require("./webpack.dll.conf")
var chalk = require("chalk")
var rm = require("rimraf")
var ora = require("ora") // 一个很好看的 loading 插件

// 配置loading的颜色和显示的信息
var spinner = ora({
    color: "green",
    text: "building for Dll..."
})
// 开启loading
spinner.start()
rm(path.resolve(__dirname, "../libs"), err => {
    if (err) throw err
    webpack(dllConfig, function(err, stats) {
        spinner.stop()
        if (err) throw err
        process.stdout.write(
            stats.toString({
                colors: true,
                modules: false,
                children: false,
                chunks: false,
                chunkModules: false
            }) + "\n\n"
        )
        console.log(chalk.cyan(" build dll succeed !.\n"))
    })
})

             3⃣️、在webpack.prod.conf.js添加Dll配置

plugins: [
    ...
    // 增加DllReferencePlugin配置
    new webpack.DllReferencePlugin({
      context: __dirname,
      manifest: require("../libs/libs-mainfest.json") // 指向生成的manifest.json
    }),
    new HtmlWebpackPlugin({
      // 增加两个变量
      libJsName: bundleConfig.libs.js,
      libCssName: bundleConfig.libs.css,
    }),
]

             然后copy打包完成的第三方库到dist文件夹下

new CopyWebpackPlugin([
   {
      from: path.resolve(__dirname, "../libs"),
      to: config.build.assetsSubDirectory,
      ignore: ["*.json"]
   }
]),

            4⃣️、在index.html中动态加入打包完成的第三方库

<% if (htmlWebpackPlugin.options.libCssName){ %>
    <link rel="stylesheet" href="./static/<%= htmlWebpackPlugin.options.libCssName %>">
    <% } %>
<% if (htmlWebpackPlugin.options.libJsName){ %>
    <script src="./static/<%= htmlWebpackPlugin.options.libJsName %>"></script>
    <% } %>

             5⃣️、执行打包第三方库的操作

                   在package的scripts中添加build:Dll

"scripts": {

   // 添加

   "build:dll": "node build/build-dll.js"

}

                   执行 npm run build build:dll即可执行对第三方库的打包操作。

        4、总结

             Dll打包以后是独立存在的,只要其包含的库没有增减、升级,hash也不会变化,因此线上的dll代码不需要随着版本发布频繁更新。使用Dll打包的基本上都是独立库文件,这类文件有一个特性就是变化不大。只要包含的库没有升级, 增减,就不需要重新打包。这样也提高了构建速度。而且也具有可移植性,如果其他项目需要相同的库,可以直接copy过去。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值