8000 提高 webpack 构建 Vue 项目的速度 · Issue #10 · lin-xin/blog · GitHub
[go: up one dir, main page]

Skip to content
8000

提高 webpack 构建 Vue 项目的速度 #10

Open

Description

@lin-xin

前言

最近有人给我的 Vue2 后台管理系统解决方案 提了 issue ,说执行 npm run build 构建项目的时候极其慢,然后就引起我的注意了。在项目中,引入了比较多的第三方库,导致项目大,而每次修改,都不会去修改到这些库,构建却都要再打包这些库,浪费了不少时间。所以,把这些不常变动的第三方库都提取出来,下次 build 的时候不再构建这些库,这样既可大大缩短构建时间。那么要怎么去实现呢?

解决方案

DllPlugin 和 DllReferencePlugin

查找了一下资料,发现我们可以利用 webpack 的插件 DllPlugin 和 DllReferencePlugin 来实现我们要的功能。

DllPlugin 可以把我们需要打包的第三方库打包成一个 js 文件和一个 json 文件,这个 json 文件中会映射每个打包的模块地址和 id,DllReferencePlugin 通过读取这个json文件来使用打包的这些模块。

接下来就看如何实现。

配置文件

在 build 文件夹中新建 webpack.dll.conf.js (项目基于 vue-cli 的)

const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    vendor: ['vue/dist/vue.common.js','vue-router', 'babel-polyfill','axios','vue-echarts-v3']
  },
  output: {
    path: path.join(__dirname, '../static/js'),
    filename: '[name].dll.js',
    library: '[name]_library'       // vendor.dll.js中暴露出的全局变量名
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, '.', '[name]-manifest.json'),
      name: '[name]_library'
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
};

然后在 package.json 中配置命令

"scripts": {
    ...
    "build:dll": "webpack --config build/webpack.dll.conf.js"
}

执行 npm run build:dll 命令来生成 vendor.dll.js 和 vendor-manifest.json

需要在 index.html 引入 vendor.dll.js

<body>
    <div id="app"></div>
    <script src="./static/js/vendor.dll.js"></script>
</body>

vendor-manifest.json 的内容大概如下:

{
  "name": "vendor_library",
  "content": {
    "./node_modules/core-js/modules/_export.js": {
      "id": 0,
      "meta": {}
    },
    ...
}

接下来就在 webpack.base.config.js 中通过 DLLReferencePlugin 来使用 DllPlugin 生成的 DLL Bundle

var webpack = require('webpack');

module.exports = {
    entry: {
        app: ['./src/main.js']
    },
    module: {
        ...
    }
    // 添加DllReferencePlugin插件
    plugins: [
        new webpack.DllReferencePlugin({
            context: path.resolve(__dirname, '..'),
            manifest: require('./vendor-manifest.json')
        }),
    ]
}

原先 build 需要 95446ms,配置之后执行 build 只需 14360ms,减少了 75% 的时间。

但是存在一个问题,当把太多的第三方依赖都打包到 vendor.dll.js 中去,该文件太大也会影响首屏加载时间。所以要权衡利弊,可以异步加载的插件就没有必要打包进来了,不要一味的把所有都打包到这里面来获取构建时的快感。

示例地址:vue-manage-system

个人博客:lin-xin/blog

Activity

  1. meidaqiao commented on May 19, 2017

    @meidaqiao

    为什么我执行npm run build:dll报错呢, 网上说添加elementUI会报错, 我去掉了还是不行, 总是报Cannot find module

  2. lin-xin commented on May 19, 2017

    @lin-xin
    OwnerAuthor

    @meitaiqiao 有问题请描述清楚!

  3. meidaqiao commented on May 19, 2017

    @meidaqiao

    我按照你的步骤新建了webpack.dll.config.js,在build文件夹, package.json也添加"build:dll": "webpack --config build/webpack.dll.conf.js"
    执行 npm run build:dll 命令来生成 vendor.dll.js 和 vendor-manifest.json
    报下面错误:
    Cannot find module '/Users/meitaiqiao/Desktop/testing/build/webpack.dll.conf.js'

  4. lin-xin commented on May 19, 2017

    @lin-xin
    OwnerAuthor

    是webpack.dll.config.js的文件名写错了。应该为webpack.dll.conf.js

  5. meidaqiao commented on May 19, 2017

    @meidaqiao

    额啊 , 汗颜汗颜, 没仔细看,

  6. lin-xin commented on May 19, 2017

    @lin-xin
    OwnerAuthor

    @meitaiqiao 不是你的问题,是我写错了。刚改了过来

  7. bitqiang commented on Jun 30, 2017

    @bitqiang

    可以异步加载的插件是啥意思。是说那些不是一开始就需要加载的插件吗?
    然后等到后面需要再加载吗

  8. lin-xin commented on Jun 30, 2017

    @lin-xin
    OwnerAuthor

    @bitqiang 是指该插件是在某个组件里才使用的,而这个组件是通过异步的方式加载的

    {
                        path: '/basetable',
                        component: resolve => require(['../components/page/BaseTable.vue'], resolve)
                    },
    
  9. webfrontzhifei commented on Jul 11, 2017

    @webfrontzhifei

    我clone了你的demo项目,在webpack.base.conf时,并没有引入DllReferencePlugin啊,去掉注释,就报错了。

  10. lin-xin commented on Jul 12, 2017

    @lin-xin
    OwnerAuthor

    @webfrontzhifei index.html 里引入的 vendor.dll.js , webpack.base.config.js 中的 DLLReferencePlugin 这些注释都要去掉。

  11. showbestriven commented on Sep 19, 2017

    @showbestriven

    我现在run dev一次 需要60秒。 使用了 dll貌似没什么提升啊 也没报错 难道是 使用错误?

  12. bitqiang commented on Sep 23, 2017

    @bitqiang

    @showbestriven 可能是共用的包没有很大影响你的打包速度。
    可以参考下我之前做的一些笔记,有需要的话。
    http://c01c1426.wiz03.com/share/s/3071gC0CI4PR2BbWAn06uEyo2k0Tkd37d4yl2Fwo460PskRH

  13. aaabinbin commented on Nov 7, 2017

    @aaabinbin

    求助大神 @lin-xin ,为啥我在vue-cli用这个dllPlugin运行的时候报,说是vue格式文件的缺少一个loader,然后同时我的vendor中已经有了element ui(包含vue结尾的文件)木有问题,就只有这个vue-quill-editor出问题了。
    ERROR in ./~/vue-quill-editor/src/editor.vue
    Module parse failed: E:\repo\baymax_static\node_modules\vue-quill-editor\src\editor.vue Unexpected token (1:0)
    You may need an appropriate loader to handle this file type.
    后来加入vue和css的loader就解决了,布吉岛为什么只有vue quill editor 有问题

  14. aaabinbin commented on Nov 7, 2017

    @aaabinbin

    发现这里的路径 ./static/js/vendor.dll.js 如果前面加了点好像就没办法在多层路由中获取文件,去掉好像就好了

    <script src="./static/js/vendor.dll.js"></script>
  15. SuperAL commented on Dec 11, 2017

    @SuperAL

    @lin-xin
    这样做是不是会导致打包后的文件体积变大啊?我对比了使用 dll 前后的 dist/static 文件夹的大小,发现差了 0.08 MB,使用 dll 的方式使得我打包后的 js 文件变大了。
    是不是 CommonsChunkPlugin 那边我需要配置什么?

  16. Maplesog commented on Dec 20, 2017

    @Maplesog

    @lin-xin 当请求的路由是两层的时候,直接在当前页面刷新。这个根目录的dll文件夹会跑到路由的目录下面去。导致请求不到。请问这是该怎么更改?
    65888978-da76-4765-9d95-98b8008efc31

    望回复。

  17. yuan252525 commented on Jan 18, 2018

    @yuan252525

    请问一个问题,我按照您提供的步骤操作的,基本配置都已经完成,打包时间确实比之前节省了4W毫秒,但是只要引入单独打包出来的那个js文件 放到服务器上就会报错.

  18. SmallBlockCat commented on Jul 17, 2018

    @SmallBlockCat

    我的报错 Uncaught ReferenceError: bundle_library is not defined 为什么呀

  19. zhengtulymGh commented on Oct 11, 2018

    @zhengtulymGh

    在html里面引用<script type="text/javascript" src="./static/js/vendor.dll.js" charset="UTF-8"></script>,使用webpack-dev-server启动的时候发现返回的是html文件怎么破?

  20. xyzshen commented on Nov 29, 2018

    @xyzshen

    没有按照你的方法npm run build 是3分44秒;按照你的方法实现了一遍还是3分44秒

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0