使用?vite?external?減小產(chǎn)物體積的方法實現(xiàn)
寫在前面
前幾個月工作過程中遇到了 Javascript heap out of memory 問題,當時想著減小前端的產(chǎn)物大小,通過 vite.external解決這問題,查了很多文章,不過都以失敗告終,經(jīng)過不懈努力和大佬的指點,終于成功了,故此分享。
前置工作
首先創(chuàng)建一個vue的項目,本地運行 pnpm dev 啟動項目
$ pnpm dev > test-external@0.0.0 dev /Users/.../test-external > vite VITE v5.4.2 ready in 138 ms ? Local: http://localhost:5173/ ? Network: use --host to expose
項目可以正常運行,執(zhí)行 pnpm build 開始構(gòu)建
$ pnpm build vite v5.4.2 building for production... ? 67 modules transformed. dist/index.html 0.51 kB │ gzip: 0.32 kB dist/assets/index-B5GNdBo.css 0.32 kB │ gzip: 0.24 kB dist/assets/index-Dwy3Kika.js 62.20 kB │ gzip: 25.16 kB
可以看到j(luò)s文件的大小為 62.20KB
設(shè)置你想要排除的依賴
比如你想你的代碼打包出來的code不包括 vue
// vite.config.ts
export default defineConfig({
build: {
rollupOptions: {
external: ['vue']
}
}
})我們再執(zhí)行下 build 命令,看看產(chǎn)物大小
$ pnpm build vite v5.4.2 building for production... ? 62 modules transformed. dist/index.html 0.51 kB │ gzip: 0.32 kB dist/assets/index-DY_q8tlo.js 8.33 kB │ gzip: 3.28 kB
可以看到j(luò)s文件大小為 8.33KB,相較于 62.20KB 小了不少,我們把代碼推送到github,部署到 github pages 看看效果
核心報錯: Failed to resolve module specifier "vue"
瀏覽器找不到名為 vue 的 ESM 模塊,因為打包產(chǎn)物里保留了 from "vue",但線上環(huán)境沒有提供這個模塊。
發(fā)現(xiàn)頁面上什么內(nèi)容都沒有,控制臺報錯,說沒有找到vue這個module,我們來看下產(chǎn)物
import {
createElementBlock as e,
createElementVNode as n,
toDisplayString as f,
ref as s,
createApp as y
} from "vue";
這里引入了vue,但是我們打包的時候,vue是排除了的,所以找不到vue,就報錯了,我之前也在這里卡住過,去網(wǎng)上查解決方法,有人說,你要通過 cdn 引入 vue,我們第二步通過cdn引入。
cdn 引入相關(guān)依賴
<!-- index.html --> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
這一步我其實剛剛在做第一步的時候就做了,還是有問題。我們來看下 vue 的 cdn 內(nèi)容
// https://unpkg.com/vue@3/dist/vue.global.js
var Vue = (function (exports) {
'use strict';
// ...
return exports;
})({});通過var聲明了一個叫 Vue 的變量,后面是一個自執(zhí)行函數(shù),但是我們的語法正常都是像上面產(chǎn)物那樣
import { ref, reactive } from 'vue';
import vue from 'vue';
這樣一想,報錯也就不奇怪了,我們要是能把 vue引入的內(nèi)容通過 Vue.xxx 替換掉,不就解決了這個問題,畢竟var聲明的變量是全局的
設(shè)置 globals
這里我之前嘗試的時候,看到網(wǎng)上很多教程讓我設(shè)置 output.globals,后來發(fā)現(xiàn)根本不生效,就去翻了rollup的文檔
output.globals
只對 umd / iife 產(chǎn)物生效,用于告訴 Rollup:某個 external 依賴在運行時對應(yīng)哪個全局變量。
文檔寫的很清楚,你要是打包成 umd 或者 iife 格式,可以設(shè)置這個參數(shù),但是我是要打包成 esm 格式(這就很尷尬了)
output.format 默認值是 es。
- es:保留為 ES module
- iife:自執(zhí)行函數(shù),適合直接通過 <script> 引入
- umd:兼容 AMD / CommonJS / IIFE 的通用格式
所以這里的關(guān)鍵問題是:我的目標產(chǎn)物是 ESM,不是 umd 或 iife,因此單獨配置 output.globals 并不能解決問題。
然后我就找到了一個rollup插件 rollup-plugin-external-globals,解決了我的問題
// vite.config.ts
import { defineConfig } from 'vite';
import externalGlobals from 'rollup-plugin-external-globals';
export default defineConfig({
plugins: [
externalGlobals({
vue: 'Vue'
})
],
build: {
rollupOptions: {
external: ['vue']
}
}
});
$ pnpm build vite v5.4.2 building for production... ? 62 modules transformed. dist/assets/index-*.js 9.59 kB
我們看到包的大小相較于 8.33KB 大了一點,為什么呢?我引入了一個插件就變大了,直接來看下產(chǎn)物
const {
createElementVNode,
openBlock,
createElementBlock,
ref,
createApp
} = Vue;沒有 import { xxx } from 'vue';,這個Vue在代碼運行的時候會沿著作用域鏈一直找到 Window,剛好我們引入的 vue cdn通過var聲明了一個Vue,這樣就對上了。至于為什么打包產(chǎn)物大小變大了,是因為字符數(shù)變多了。我們推下代碼,驗證下想法
控制臺不再出現(xiàn) Failed to resolve module specifier "vue" 的報錯。
大功告成!??!
QA
為什么要設(shè)置 external ?我直接設(shè)置cdn,代碼里面不用import,也能行啊 ??? ?
這么做確實沒啥問題,代碼也能正常運行,部署到生產(chǎn)也不會有啥問題,不用import,就失去了類型提示,引入提示等依賴帶來的好處,內(nèi)容都是有上下文的,不會覺得奇怪
為什么這套配置開發(fā)環(huán)境下有問題
由于vite的開發(fā)環(huán)境用的是esbuild,打包用的是rollup,而rollup-plugin-external-globals插件是rollup插件,不建議在開發(fā)環(huán)境使用,以避免引起不必要的麻煩
/// vite.config.ts
import { defineConfig } from 'vite';
import externalGlobals from "rollup-plugin-external-globals";
const isProduction = process.env.NODE_ENV === 'production'
export default defineConfig(() => {
return {
plugins: [
...,
isProduction && externalGlobals({
vue: "Vue"
})
],
}
})
寫在最后
到此這篇關(guān)于使用 vite external 減小產(chǎn)物體積的文章就介紹到這了,更多相關(guān)vite external 減小體積內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue中splice()方法對數(shù)組進行增刪改等操作的實現(xiàn)
vue中對數(shù)組的元素進行刪除,以前一直以為這個方法是vue中特有的,后來百度之后才知道原來是js的一個寫法,下面這篇文章主要給大家介紹了關(guān)于Vue中splice()方法對數(shù)組進行增刪改等操作的實現(xiàn)方法,需要的朋友可以參考下2023-05-05
Vue+Echarts實現(xiàn)繪制動態(tài)折線圖
這篇文章主要為大家詳細介紹了如何利用Vue和Echarts實現(xiàn)繪制動態(tài)折線圖,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2023-03-03
Vue?keepAlive實現(xiàn)不同的路由共用一個組件component的緩存問題(推薦)
這篇文章主要介紹了Vue?keepAlive實現(xiàn)不同的路由共用一個組件component的緩存問題,實現(xiàn)方式使用Vue?keepAlive實現(xiàn)頁面緩存,需要的朋友可以參考下2022-08-08

