【译】如何使用webpack减少vuejs打包的大小

banner

我在Stanley Black & Decker的工业4.0团队工作。我们的团队最近为Stanley制造工厂创建了相当于App Store的产品。工厂可以访问市场并根据他们在该位置生产的产品选择他们需要的应用程序。这将构建一个自定义构建,将所有这些应用程序捆绑在一起,以便工厂运行。由于捆绑了如此众多的应用程序,我们的vue生产构建时,导致多个大小过度的警告。

我们最初的构建规模

当我们进行构建时,我们收到以下2条错误消息:

two_error

Vue建议捆版bundles不超过244KiB。我们只有14个资源,每个资源都超过这个规模。此外,我们有四个入口点也高于建议的大小。以下是我将构建的大小减半的方法。

导致大型构建包的原因是什么?

首先,我需要了解导致大型构建包大小的原因。为此,我安装了webpack-bundle-analyzer。这将提供每个包中项目大小的可视指南。

npm install --save-dev webpack-bundle-analyzer

接下来,我在vue.config.js文件中配置webpack来使用它。下面是我的配置文件vue.config.js的内容:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
    .BundleAnalyzerPlugin;
    module.exports = {
        configureWebpack: {
            plugins: [new BundleAnalyzerPlugin()]
        }
   };

安装完插件后,我再次运行构建,我可以看到我的构建大小是2.48MB。从图像中我可以看到最大的罪魁祸首是:

  • vue-echarts
  • vuetify
  • moment
  • lodash
biggest_culprits

减少Lodash的大小

Lodash占用了70.7kb的空间。Lodash仅在我们的框架中的所有应用程序中的两个位置使用。这只是两种方法的大量空间。

lodash

我们不止加载了lodash,我们也加载了vue-lodash。第一步是移除package.json中没有使用到的vue-lodash

下一步是仅从lodash导入我们需要的两个项目(库)。我们使用的是cloneDeep和sortBy。我替换了导入整个lodash库的初始调用:

import _ from 'lodash';

我正在用这个只导入我们需要的两个项目(库)的调用替换它。为此,我将导入从lodash更改为lodash/core

import { cloneDeep, sortBy } from 'lodash/core';

进行这一更改后,我的构建包的大小从2.48MB减少到2.42MB。这是显示构建的当前大小的图像。

optimize_lodash_graph

在这里我们可以看到lodash本身作为构建包一部分的大小。

optimize_lodash_itself

减少moment.js的大小

Moment.js在构建包中占了234.36KB。当你查看图片的时,该大小的绝大部分是它们支持的所有语言的国际化语言环境。我们根本没有使用moment.js的这一部分,所以我们打包中包含了不必要部分。

幸运的是,我们可以删除它。而不是使下面的调用导入所有moment.js

import moment form 'moment';

我们只能通过此调用导入日期操作代码:

import moment from 'moment/src/moment'

至少在我们的代码库中进行替换是一个问题。有18个地方在代码中导入了moment.js。我本可以在代码中进行全局搜索和替换。但是如果我们向框架添加一个新的应用程序,开发人员很可能会使用默认调用来导入moment.js。如果他们这样做,那么我们将再次导入所有国际语言环境。

因此,权衡之后,在webpack中创建一个快捷方式的别名。该快捷方式将用moment/src/moment替换所有导入moment的调用。我们可以使用resolve和设置别名在我们的vue.config.js文件添加该别名。这是我vue.config.js现在的样子。

webpack_alia

当我们现在运行构建时,我们的捆绑包现在已经下降到2.22MB的大小了。

optimize_moment

当你查看图像的moment.js时,你将看到国际化区域设置根本不再被加载。

optimize_moment_after

通过删除moment.js中的语言环境,每当我启动服务器运行我的代码时都会发生错误,该错误代码说它无法找到./locale。在做了一些研究之后,我发现这已经成为了moment.js的一个已知好几年的问题,moment.js总是加载并假定locales是现在。你无法分辨加载日期操作功能的时刻。

要解决这个问题,我使用内置的webpack IgnorePlugin忽略此消息。这是我添加到我的vue.config.js文件中的插件代码:

new webpack.IgnorePlugin(/^\\.\\/locale$/, /moment$/)

减少Vuetify.js的大小

我的下一个目标是Vuetify.js的大小。Vuetify占用空间500.78KB。对于一个供应商产品来说,这是一个巨大的空间。

vuetify

Vuetify提供了一种他们称之为点菜的功能。这允许你仅导入你使用的Vuetify组件。这会减少Vuetify的大小。挑战在于我们有如此多的应用程序正在进行并试图确定我们正在使用的组件不会改变。

在当前版本的Vuetify(当我写这篇文章的时候版本为1.56)中,他们提供了一个名为vuetify-loader的产品。 它将遍历你的代码并确定你正在使用的所有组件,然后将它们只导入你的构建包。 ⚠️注意:最终vuetify v2将内置此功能。 在该版本可用之前,你必须使用vuetify-loader仅导入你正在使用的组件。 Vuetify文档说明要获得所有必需的样式,我们需要在stylus中导入它们。

我意识到我们正在运行旧版本的vuetify.js。 所以我决定将我的vuetify版本升级到最新版本。我还同时安装了stylevuetify-loader

npm install vuetify vuetify-loader stylus stylus-loader style-loader css-loader --save

我导入Vuetify的插件代码有一些主题的自定义,以使用我们公司的调色板。 以下是我目前的Vuetify插件:

current_vuetify_plugin

我需要将Vuetify的导入更改为从vuetify/lib导入。 我还将导入stylus以获得所有样式。 这是我的插件代码现在的样子:

current_vuetify_plugin02

最后一步是告诉webpack使用vuetify-loader插件,以便它只导入我们正在使用的组件。 我将需要的插件添加到插件数组。 这是我的vue.config.js文件:

current_vuetify_plugin03

现在,当我运行生产构建时,我的捆绑包大小为2MB

optimize_vuetify_after

减少vue-echarts的大小

Vue-echarts不是我捆绑中最大的项目。 Vue-echarts运行在echarts之上。 和Vuetify一样,我正在运行两种产品的旧版本。 将它们升级到最新版本我运行此命令:

npm install echarts vue-echarts --save

我对vue-echarts GitHub repo进行了一些研究,查看所有已关闭的问题,发现最新版本的vue-echarts允许你通过更改导入的内容来加载较小的包。 以前我使用此命令导入它:

import ECharts from 'vue-echarts';

我改成这种:

import ECharts from 'vue-echarts/components/ECharts.vue';

现在,当我运行生产构建时,我的捆绑包大小降至1.28MB。

optimize_vue_echart

总结

我的目标是减少为我们的应用程序生产而创建的包的大小。 我的构建的初始大小是2.48MB。 通过进行一些更改,我能够将构建大小减少到1.2MB。 这几乎减少了50%

如果要创建生产环境Vue应用程序,则应该花时间来评估构建大小。 使用webpack-bundle-analyzer确定哪些项目占用的空间最多。 然后开始采取必要步骤来减少这些项目的大小。 我能够通过这种方式减少捆绑中四个最大项目的大小。

希望对你有帮助,能按照这些步骤来减少生产构建包的大小。

参考和后话

更多的内容,请戳我的博客进行了解,能留个star就更好了💨

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

推荐阅读更多精彩内容