17 提高构建性能

2019-12-24  本文已影响0人  辣瓜瓜

webpack提高构建性能方式

  1. 尽可能少用loader;
  2. 使用babel-loader时,指定代码转译范围;
include: path.resolve(__dirname,'../src') ,//仅对指定路径下文件进行转译
exclude: /node_modules/ //避免对node_modules中的文件进行转译
  1. 使用noParse避免对引入的第三方模块(如jquery|bootstrap)解析内部依赖关系,减少打包时间;
  2. 使用IgnorePlugin,忽略第三方模块内部依赖的其他模块;
  3. 使用DllPlugin,对几乎不变的第三方模块、框架只进行一次打包,以后仅打包业务代码;
  4. Happypack、thread-loader 多进程打包(不适合webpack4,已过时,不推荐使用)

noParse

webpack性能的表现之一就是打包速度,打包速度常依赖于项目的规模,如果项目规模本身比较大,如过能提升打包速度就更好了

在引入一些第三方模块时,例如jQuery、bootstrap等,我们知道其内部肯定不会依赖其他模块,因为最终我们用到的只是一个单独的js文件或css文件

所以此时如果webpack再去解析他们的内部依赖关系,其实是非常浪费时间的,我们需要阻止webpack浪费精力去解析这些明知道没有依赖的库,从而减少了打包所需要的时间

可以在webpack配置文件的module节点下加上noParse,并配置正则来确定不需要解析依赖关系的模块

 webpack.base.js
 module.exports = merge(baseWebpackConfig, {
   //optimization: { },
   module: {
    noParse: /jquery|bootstrap/
   }
   ...
 }

IgnorePlugin

在引入一些第三方模块时,例如moment,内部会做i18n国际化处理,所以会包含很多语言包,而语言包打包时会比较占用空间,如果我们项目只需要用到中文,或者少数语言,可以忽略掉所有的语言包,然后按需引入语言包

从而使得构建效率更高,打包生成的文件更小

需要忽略第三方模块内部依赖的其他模块,只需要三步:

  1. 首先要找到moment依赖的语言包是什么
  2. 使用IgnorePlugin插件忽略其依赖
  3. 需要使用某些依赖时自行手动引入

具体实现如下:

  1. 通过查看moment的源码来分析:

    function loadLocale(name) {
        var oldLocale = null;
        // TODO: Find a better way to register and load all the locales in Node
        if (!locales[name] && (typeof module !== 'undefined') &&
            module && module.exports) {
            try {
                oldLocale = globalLocale._abbr;
                var aliasedRequire = require;
                aliasedRequire('./locale/' + name);
                getSetGlobalLocale(oldLocale);
            } catch (e) {}
        }
        return locales[name];
    }
    
    

    观察上方代码,同时查看moment目录下确实有locale目录,其中放着所有国家的语言包,可以分析得出:locale目录就是moment所依赖的语言包目录

  2. 使用IgnorePlugin插件来忽略掉moment模块的locale目录

    在webpack配置文件中安装插件,并传入配置项

    参数1:表示要忽略的资源路径

    参数2:要忽略的资源上下文(所在哪个目录)

    两个参数都是正则对象

    new webpack.IgnorePlugin(/\.\/locale/, /moment/)
    
  3. 使用moment时需要手动引入语言包,否则默认使用英文

    import moment from 'moment'
    import 'moment/locale/zh-cn'
    moment.locale('zh-CN')
    console.log(moment().subtract(6, 'days').calendar())
    

DllPlugin

在引入一些第三方模块时,例如vue、react、angular等框架,这些框架的文件一般都是不会修改的,而每次打包都需要去解析它们,也会影响打包速度,哪怕做拆分,也只是提高了上线后用户访问速度,并不会提高构建速度,所以如果需要提高构建速度,应该使用动态链接库的方式,类似于Windows中的dll文件。

借助DllPlugin插件实现将这些框架作为一个个的动态链接库,只构建一次,以后每次构建都只生成自己的业务代码,可以大大提高构建效率!

主要思想在于,将一些不做修改的依赖文件,提前打包,这样我们开发代码发布的时候就不需要再对这部分代码进行打包,从而节省了打包时间。

涉及两个插件:

  1. DllPlugin

    使用一个单独webpack配置创建一个dll文件。并且它还创建一个manifest.json。DllReferencePlugin使用该json文件来做映射依赖性。(这个文件会告诉我们的哪些文件已经提取打包好了)

    配置参数:

    • context (可选): manifest文件中请求的上下文,默认为该webpack文件上下文。
    • name: 公开的dll函数的名称,和output.library保持一致即可。
    • path: manifest.json生成的文件夹及名字
  2. DllReferencePlugin

    这个插件用于主webpack配置,它引用的dll需要预先构建的依赖关系。

    • context: manifest文件中请求的上下文。

    • manifest: DllPlugin插件生成的manifest.json

    • content(可选): 请求的映射模块id(默认为manifest.content)

    • name(可选): dll暴露的名称

    • scope(可选): 前缀用于访问dll的内容

    • sourceType(可选): dll是如何暴露(libraryTarget)

将Vue项目中的库抽取成Dll

  1. 准备一份将Vue打包成DLL的webpack配置文件

    在build目录下新建一个文件:webpack.vue.js

    配置入口:将多个要做成dll的库全放进来

    配置出口:一定要设置library属性,将打包好的结果暴露在全局

    配置plugin:设置打包后dll文件名和manifest文件所在地

    const path = require('path')
    const webpack = require('webpack')
    module.exports = {
      mode: 'development',
      entry: {
        vue: [
          'vue/dist/vue.js',
          'vue-router'
        ]
      },
      output: {
        filename: '[name]_dll.js',
        path: path.resolve(__dirname, '../dist'),
        library: '[name]_dll'
      },
      plugins: [
        new webpack.DllPlugin({
          name: '[name]_dll',
          path: path.resolve(__dirname, '../dist/manifest.json')
        })
      ]
    }
    
  2. 在webpack.base.js中进行插件的配置

    使用DLLReferencePlugin指定manifest文件的位置即可

    plugins: [
        new webpack.DllReferencePlugin({
          manifest: path.resolve(__dirname, '../dist/manifest.json')
        })
    ]
    
  3. 安装add-asset-html-webpack-plugin

    npm i add-asset-html-webpack-plugin -D

  4. 配置插件自动添加script标签到HTML中

    new AddAssetHtmlWebpackPlugin({
      filepath: path.resolve(__dirname, '../dist/vue_dll.js')
    })
    

将React项目中的库抽取成Dll

  1. 准备一份将React打包成DLL的webpack配置文件

    在build目录下新建一个文件:webpack.vue.js

    配置入口:将多个要做成dll的库全放进来

    配置出口:一定要设置library属性,将打包好的结果暴露在全局

    配置plugin:设置打包后dll文件名和manifest文件所在地

    const path = require('path')
    const webpack = require('webpack')
    module.exports = {
      mode: 'development',
      entry: {
        react: [
          'react',
          'react-dom'
        ]
      },
      output: {
        filename: '[name]_dll.js',
        path: path.resolve(__dirname, '../dist'),
        library: '[name]_dll'
      },
      plugins: [
        new webpack.DllPlugin({
          name: '[name]_dll',
          path: path.resolve(__dirname, '../dist/manifest.json')
        })
      ]
    }
    
  2. 在webpack.base.js中进行插件的配置

    使用DLLReferencePlugin指定manifest文件的位置即可

    new webpack.DllReferencePlugin({
      manifest: path.resolve(__dirname, '../dist/manifest.json')
    })
    
  3. 安装add-asset-html-webpack-plugin

    npm i add-asset-html-webpack-plugin -D

  4. 配置插件自动添加script标签到HTML中

    new AddAssetHtmlWebpackPlugin({
      filepath: path.resolve(__dirname, '../dist/react_dll.js')
    })
    
上一篇 下一篇

猜你喜欢

热点阅读