前言
前几个月工作过程中遇到了 Javascript heap out of memory
问题,当时想着减小前端的产物大小,通过 vite.external
解决这问题,查了很多文章,不过都以失败告终,经过不懈努力和大佬的指点,终于成功了,故此分享。
前置工作
首先创建一个vue的项目(不清楚的掘友点击这里 cn.vuejs.org/guide/quick…)
本地运行 pnpm dev
启动项目
项目可以正常运行,执行 pnpm build
开始构建
可以看到js文件的大小为 62.20KB
打包出来的目录为 docs
,是因为我配置了 output.dir
,想了解更多信息可以访问 rollupjs.org/configurati…
步骤
设置你想要排除的依赖
比如你想你的代码打包出来的code不包括 vue
/// vite.config.ts
export default defineConfig({
build: {
rollupOptions: {
external: ['vue']
}
}
})
我们再执行下 build
命令,看看产物大小
可以看到js文件大小为 8.33KB
,相较于 62.20KB
小了不少,我们把代码推送到github,部署到 github pages 看看效果
发现页面上什么内容都没有,控制台报错,说没有找到vue这个module,我们来看下产物
这里引入了vue,但是我们打包的时候,vue是排除了的,所以找不到vue,就报错了,我之前也在这里卡住过,去网上查解决方法,有人说,你要通过 cdn
引入 vue
那我们第二步通过cdn引入
cdn 引入相关依赖
这一步我其实刚刚在做第一步的时候就做了,还是有问题。我们来看下 vue 的 cdn 内容
通过var声明了一个叫 Vue
的变量,后面是一个自执行函数,但是我们的语法正常都是像上面产物那样
import { ref, reactive } from 'vue';
import vue from 'vue';
这样一想,报错也就不奇怪了,我们要是能把 vue引入的内容通过 Vue.xxx
替换掉,不就解决了这个问题,毕竟var声明的变量是全局的
设置 globals
这里我之前尝试的时候,看到网上很多教程让我设置 output.globals
,后来发现根本不生效,就去翻了 rollupjs.org/configurati…
文档写的很清楚,你要是打包成 umd
或者 iife
格式,可以设置这个参数,但是我是要打包成 esm
格式(这就很尴尬了)
然后我就找到了一个rollup插件 rollup-plugin-external-globals
,解决了我的问题
我们看到包的大小相较于 8.33KB
大了一点,为什么呢?我引入了一个插件就变大了,直接来看下产物
眼尖的掘友已经发现了,没有 import { xxx } from 'vue';
,那vue呢
这个Vue在代码运行的时候会沿着作用域链一直找到 Window,刚好我们引入的 vue cdn通过var声明了一个Vue,这样就对上了。至于为什么打包产物大小变大了,是因为字符数变多了。
我们推下代码,验证下想法
大功告成!!!
疑问
为什么要设置 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"
})
],
}
})
结尾
如有错误,欢迎指正