17 提高构建性能

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')
    })
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容