如何使用 Webpack 减小 Vue.js 的打包大小
我在史丹利百得公司的工业4.0团队工作。我们团队最近为史丹利全球各地的制造工厂创建了一个类似应用商店的平台。工厂可以访问该平台,并根据其生产的产品选择所需的应用程序。系统会生成一个定制版本,将所有这些应用程序打包在一起供工厂运行。由于打包的应用程序数量庞大,我们用于生产环境的Vue构建版本出现了多个关于体积过大的警告。
我们最初的建筑规模
构建时,我们收到以下 2 条错误消息:
Vue 建议打包文件大小不要超过 244 KiB。我们只有 14 个资源文件超过了这个大小。此外,还有 4 个入口点也超过了建议的大小。以下是我为了将构建文件大小减半而采取的措施。
是什么原因导致构建包过大?
首先,我需要了解导致构建包体积过大的原因。为此,我安装了 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
- 片刻
- lodash
减小 Lodash 的大小
Lodash 占用了 70.74kb 的空间。在我们的框架的所有应用程序中,Lodash 只在两处使用。仅仅两个方法就占用了这么多空间,实在令人难以接受。
我们不仅加载了 lodash,还加载了 vue-lodash。第一步是从 package.json 文件中移除 vue-lodash,因为它不再需要了。
下一步是从 lodash 中仅导入我们需要的两个组件,而不是加载整个库。我们使用的是 `<module>` 和 `<module>` cloneDeep 。 sortBy我替换了最初导入整个 lodash 库的调用:
import _ from 'lodash';
我用这个只导入我们需要的两个项目的调用替换了它。为此,我将导入语句从 lodash 改为 lodash/core:
import { cloneDeep, sortBy } from 'lodash/core';
仅仅做了这一处改动,我的构建包大小就从 2.48MB 减少到了 2.42MB。下图显示了当前构建包的大小。
在这里我们可以看到 lodash 本身作为构建包的一部分的大小。
减小 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' 的调用替换为 'moment/src/moment'。我们可以使用 resolve 并设置别名,将该别名添加到 vue.config.js 文件中。以下是我的 vue.config.js 文件现在的样子。
现在我运行生产环境的构建时,我们的打包文件大小已经降至 2.22MB。
当你查看图片中的 moment.js 文件时,你会发现国际化语言环境完全没有被加载。
移除 moment.js 中的语言环境后,每次启动服务器运行代码时都会出现错误,提示找不到语言环境 ./locale。经过一番研究,我发现这其实是 moment.js 多年来的一个已知问题:它总是默认加载语言环境。你无法指示 moment 只加载日期操作功能。
为了解决这个问题,我使用了 webpack 内置的 IgnorePlugin 插件来忽略这条消息。以下是我添加到 vue.config.js 文件中的插件代码:
new webpack.IgnorePlugin(/^\\.\\/locale$/, /moment$/)
减小 Vuetify.js 的大小
接下来我想解决的是 Vuetify.js 的大小。Vuetify 占用了 500.78KB 的空间。对于一个厂商的产品来说,这空间占用太大了。
Vuetify 提供了一个名为“按需导入”(a-la-carte)的功能。它允许您仅导入您使用的 Vuetify 组件,从而减小 Vuetify 的体积。但问题在于,我们的应用程序数量庞大,逐一确定我们正在使用的组件是不现实的。
在当前版本的 Vuetify(我撰写本文时版本为 1.56)中,他们提供了一个名为 vuetify-loader 的产品。它会遍历你的代码,确定你使用的所有组件,然后将它们导入到你的构建包中。 注意: Vuetify v2 最终会内置此功能。在此版本发布之前,你必须使用 vuetify-loader 来导入你正在使用的组件。Vuetify 文档指出,要获取所有必需的样式,我们需要在 Stylus 中导入它们。
我发现我们运行的是旧版本的 vuetify.js。所以我决定将 vuetify 版本升级到最新版本。我还同时安装了样式和 vuetify-loader,命令如下:
npm install vuetify vuetify-loader stylus stylus-loader style-loader css-loader --save
我用于导入 Vuetify 的插件代码对主题进行了一些自定义,使其使用我们公司的配色方案。以下是我的 Vuetify 插件的当前代码:
我需要修改 Vuetify 的导入语句,使其从 vuetify/lib 导入。我还会导入 Stylus 来获取所有样式。以下是我的插件代码:
最后一步是告诉 webpack 使用 vuetify-loader 插件,这样它就只会导入我们正在使用的组件。我会先引入该插件,然后将其添加到 plugins 数组中。以下是我的 vue.config.js 文件:
现在当我运行生产环境构建时,我的打包大小为 2MB。
减小 vue-echarts 的大小
Vue-echarts 并不是我软件包中最大的组件。Vue-echarts 运行在 echarts 之上。和 Vuetify 一样,我目前使用的是这两个产品的旧版本。为了将它们都升级到最新版本,我运行了以下命令:
npm install echarts vue-echarts --save
我在 vue-echarts 的 GitHub 代码库中查阅了所有已关闭的问题,发现最新版本的 vue-echarts 允许通过更改导入语句来加载更小的包。之前我使用以下命令导入:
import ECharts from 'vue-echarts';
我把它改成这样:
import ECharts from 'vue-echarts/components/ECharts.vue';
现在当我运行生产环境构建时,我的打包大小降到了 1.28MB。
结论
我的目标是减小应用程序生产环境部署包的大小。最初构建包的大小为 2.48MB。通过一些修改,我成功地将构建包的大小减少到 1.2MB,减少了近 50%。
如果你正在开发生产环境的 Vue 应用,你应该花时间评估一下构建包的大小。使用 webpack-bundle-analyzer 来确定哪些文件占用了最多的空间。然后采取必要的措施来减小这些文件的大小。我就是这样成功地减小了打包文件中最大的四个文件的大小。
希望这些步骤能帮助您减小生产环境的构建包大小。如有任何疑问或意见,请在下方留言。非常感谢您的阅读。
培训课程
我在我的网站 CodePrep 上创建培训课程。课程内容涵盖 Vue、Webpack、Flexbox、函数式编程等等。点击这里查看。
文章来源:https://dev.to/ratracegrad/how-to-reduce-your-vue-js-bundle-size-with-webpack-4gpf













