【譯】如何使用webpack減少vuejs打包的大小

call_me_R發表於2019-07-30

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就更好了?

相關文章