使用 vite external 减小产物体积的方法实现

 更新时间:2026年05月20日 15:28:11   作者:前端毕业班  
本文主要介绍了使用 vite external 减小产物体积,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

写在前面

前几个月工作过程中遇到了 Javascript heap out of memory 问题,当时想着减小前端的产物大小,通过 vite.external解决这问题,查了很多文章,不过都以失败告终,经过不懈努力和大佬的指点,终于成功了,故此分享。

前置工作

首先创建一个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

项目可以正常运行,执行 pnpm build 开始构建

$ 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

可以看到js文件的大小为 62.20KB

设置你想要排除的依赖

比如你想你的代码打包出来的code不包括 vue

// vite.config.ts
export default defineConfig({
  build: {
    rollupOptions: {
      external: ['vue']
    }
  }
})

我们再执行下 build 命令,看看产物大小

$ 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

可以看到js文件大小为 8.33KB,相较于 62.20KB 小了不少,我们把代码推送到github,部署到 github pages 看看效果

核心报错: Failed to resolve module specifier "vue"

浏览器找不到名为 vue 的 ESM 模块,因为打包产物里保留了 from "vue",但线上环境没有提供这个模块。

发现页面上什么内容都没有,控制台报错,说没有找到vue这个module,我们来看下产物

import {
  createElementBlock as e,
  createElementVNode as n,
  toDisplayString as f,
  ref as s,
  createApp as y
} from "vue";

这里引入了vue,但是我们打包的时候,vue是排除了的,所以找不到vue,就报错了,我之前也在这里卡住过,去网上查解决方法,有人说,你要通过 cdn 引入 vue,我们第二步通过cdn引入。

cdn 引入相关依赖

<!-- index.html -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

这一步我其实刚刚在做第一步的时候就做了,还是有问题。我们来看下 vue 的 cdn 内容

// https://unpkg.com/vue@3/dist/vue.global.js
var Vue = (function (exports) {
  'use strict';
  // ...
  return exports;
})({});

通过var声明了一个叫 Vue 的变量,后面是一个自执行函数,但是我们的语法正常都是像上面产物那样

import { ref, reactive } from 'vue';

import vue from 'vue';

这样一想,报错也就不奇怪了,我们要是能把 vue引入的内容通过 Vue.xxx 替换掉,不就解决了这个问题,毕竟var声明的变量是全局的

设置 globals

这里我之前尝试的时候,看到网上很多教程让我设置 output.globals,后来发现根本不生效,就去翻了rollup的文档

output.globals

只对 umd / iife 产物生效,用于告诉 Rollup:某个 external 依赖在运行时对应哪个全局变量。

文档写的很清楚,你要是打包成 umd 或者 iife 格式,可以设置这个参数,但是我是要打包成 esm 格式(这就很尴尬了)

output.format 默认值是 es。

  • es:保留为 ES module
  • iife:自执行函数,适合直接通过 <script> 引入
  • umd:兼容 AMD / CommonJS / IIFE 的通用格式

所以这里的关键问题是:我的目标产物是 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 大了一点,为什么呢?我引入了一个插件就变大了,直接来看下产物

const {
  createElementVNode,
  openBlock,
  createElementBlock,
  ref,
  createApp
} = Vue;

没有 import { xxx } from 'vue';,这个Vue在代码运行的时候会沿着作用域链一直找到 Window,刚好我们引入的 vue cdn通过var声明了一个Vue,这样就对上了。至于为什么打包产物大小变大了,是因为字符数变多了。我们推下代码,验证下想法

控制台不再出现 Failed to resolve module specifier "vue" 的报错。

大功告成!!!

QA

为什么要设置 external ?我直接设置cdn,代码里面不用import,也能行啊 🤔️ ?

这么做确实没啥问题,代码也能正常运行,部署到生产也不会有啥问题,不用import,就失去了类型提示,引入提示等依赖带来的好处,内容都是有上下文的,不会觉得奇怪

为什么这套配置开发环境下有问题

由于vite的开发环境用的是esbuild,打包用的是rollup,而rollup-plugin-external-globals插件是rollup插件,不建议在开发环境使用,以避免引起不必要的麻烦

/// 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"
      })
   ],
  }
})

写在最后

到此这篇关于使用 vite external 减小产物体积的文章就介绍到这了,更多相关vite external 减小体积内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue使用html2canvas和jspdf实现PDF文件导出

    Vue使用html2canvas和jspdf实现PDF文件导出

    这篇文章主要为大家详细介绍了Vue如何使用html2canvas和jspdf实现PDF文件导出功能并设置页面大小及方向,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-01-01
  • vue3中vue-router安装配置使用全过程

    vue3中vue-router安装配置使用全过程

    VueRouter是Vue.js官方的路由管理器,用于实现单页面应用(SPA)的路由功能,这篇文章主要介绍了vue3中vue-router安装配置使用的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-09-09
  • vue+Element-ui前端实现分页效果

    vue+Element-ui前端实现分页效果

    这篇文章主要为大家详细介绍了vue+Element-ui前端实现分页效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • vue路由结构可设一层方便动态添加路由操作

    vue路由结构可设一层方便动态添加路由操作

    这篇文章主要介绍了vue路由结构可设一层方便动态添加路由操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • webstrom Debug 调试vue项目的方法步骤

    webstrom Debug 调试vue项目的方法步骤

    这篇文章主要介绍了webstrom Debug 调试vue项目的方法步骤,详细的介绍了两种调试vue项目的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • vuex 实现getter值赋值给vue组件里的data示例

    vuex 实现getter值赋值给vue组件里的data示例

    今天小编就为大家分享一篇vuex 实现getter值赋值给vue组件里的data示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Vue之计算属性详解

    Vue之计算属性详解

    这篇文章主要为大家介绍了Vue的计算属性,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • 用v-html解决Vue.js渲染中html标签不被解析的问题

    用v-html解决Vue.js渲染中html标签不被解析的问题

    这篇文章主要给大家介绍了如何利用v-html解决Vue.js渲染过程中html标签不能被解析,html标签显示为字符串的问题,文中通过图文介绍的很详细,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • vue操作下拉选择器获取选择的数据的id方法

    vue操作下拉选择器获取选择的数据的id方法

    今天小编就为大家分享一篇vue操作下拉选择器获取选择的数据的id方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • 深入浅析vue全局环境变量和模式

    深入浅析vue全局环境变量和模式

    这篇文章主要介绍了vue全局环境变量和模式的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04

最新评论