vue项目,使用DllPlugin减少打包时间的配置

写在前面:

参考了许多资料,都差不多的,但是并不是很全,过程有点头疼

项目前提:

index.html文件(在主目录下的)

<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <title></title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
  <link rel="stylesheet" href="/dist/main.css">
</head>

<body>
<div id="app"></div>
<script type="text/javascript" src="/common/js/vendor.js"></script> <!--对应dllPlugin生成的js-->
<script type="text/javascript" src="/dist/main.js"></script>
</body>

</html>

1、在build目录下新建:

文件webpack.dll.config.js
const path = require("path");
const webpack = require("webpack");
//读取package.json里的依赖,normalize.css除外,打包会报错
const package = require('../package.json');
let dependencies = Object.keys(package.dependencies) || [];
//如果使用了chrome的vue-devtool,那打包的时候把vue也排除掉,因为压缩过的vue是不能使用vue-devtool的
dependencies = dependencies.length > 0 ? dependencies.filter(item => item !== 'vue') : [];

module.exports = {
  devtool: 'source-map',
  entry: {
    vendor: dependencies // "vendor"这个名字是自己定义的
  },
  output: {
    path: path.join(__dirname, "../common/js"), // 输出的文件放在common/js中
    filename: "[name].js", // 其中[name]就是entry中的vendor,因此filename就是vendor.js
    library: "[name]" // vendor.js中暴露出的全局变量名
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, ".", "[name]-manifest.json"), // DllReferencePlugin使用该json文件来做映射依赖性。(这个文件会告诉我们的哪些文件已经提取打包好了)
      name: "[name]",  //  暴露出的dll的函数名;此处需要和 output.library 的值一致
      context: __dirname 
    }),
    new webpack.optimize.UglifyJsPlugin({ // 压缩
      compress: {
        warnings: false
      }
    })
  ]
};

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

2、在package.json的脚本中,添加如下脚本

"build:dll": "webpack --config build/webpack.dll.config.js"

3、运行npm run build:dll会生成两个文件:build文件夹下的vendor-manifest.json和common/js下的vendor.js

4、然后,在webpack.prod.config.js(生产环境)中添加以下代码:

    new webpack.DllReferencePlugin({
      context: __dirname,
      manifest: require('./vendor-manifest.json')
    }),

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

此时输入命令npm run dev,会发现项目编译的时间缩短(特别是之前项目编译时间越久变化越明显)

我看到不同的资料里,这段代码被放在生产环境或者webpack主配置文件中了,因此,我尝试将这段代码放在webpack.base.config.js中。此时再次输入命令npm run dev编译,会发现项目编译的时间又缩短了

5、之后我们在打包项目的时候,发现报错:vendor.js is undefined

这是因为vendorjs没有被打包到目标文件内,并且没有添加到HtmlWebpackPlugin生成的html文件(的script脚本链接)

解决方式:

6、安装插件: "add-asset-html-webpack-plugin"

在安装之前需要注意对应的html-webpack-plugin的版本要在2.10.0以上:

运行下面语句安装:

npm install [email protected] --save-dev

注意:在这里有一个坑,要安装一个合适版本的插件,高版本的这个插件会报如下错误:

Cannot read property 'compilation' of undefined

笔者降低了版本才得以解决,现在最新的是3.1.3,降低来安装了2.1.2版本的

7、安装之后,在webpack.pro.config.js(生产环境)中添加如下代码:

const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
    ...
    plugins: {
        new AddAssetHtmlPlugin({
          filepath: path.resolve(__dirname, '../common/js/vendor.js'),
          outputPath: path.posix.join('', '../common/js'),
          publicPath: '/common/js',
          includeSourcemap: false
        }),
    }
}

在这里,笔者也碰到了一些坑:

filepath接收的是String或Glob类型,是dllPlugin打包生成js(即vendor.js)的绝对路径

outputpath是输出的路径,posix是为了兼容,跨平台,path.join拼接路径;(参考https://blog.csdn.net/wbiokr/article/details/73612207 学习node的path模块)

publicPath:接收的是String类型,官网解释:If set, will be used as the public path of the script or link tag.也就是说是用于脚本或者链接的公共路径,笔者这里原来是下面这样写的:

publicPath: path.join('', '/common/js'),

但是每一次打包之后,生成的目标index.html中的引用脚本的斜杠会被转义为反斜杠:

<script type="text/javascript" src="\common\js/vendor.js"></script>

这样子很不好看,而且可能会带来潜在问题(具体啥问题还不清楚)

后面使用了字符串(本来接收的就是字符串,汗-_-||)

includeSourcemap应该被设置为false,设置为true时,在打包过程中,vendor.js文件会被添加上.map的后缀,导致报错说找不到vendor.js.map文件。

8、最后成功打包

参考资料:

https://www.jianshu.com/p/ec86c9e64560

https://blog.csdn.net/wxl1555/article/details/80196180

https://www.jianshu.com/p/862c56479456

推荐:Webpack 打包优化之体积篇

感觉能够帮助我们了解项目应该做哪些优化

发布了51 篇原创文章 · 获赞 33 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/shelbyandfxj/article/details/88695266
今日推荐