借鉴的文章有:
- 解决Vue3.0+Vite项目打包后低版本浏览器兼容性问题
- Vite解决报错(Top-level await is not available in the configured target environment)
- vite 打包 es5
这几天碰到一个需求,组长说让我对vite项目兼容一下低版本,以及对于顶层await打包报错问题处理
一、vite浏览器兼容性
Vite 是一个面向现代浏览器的构建工具,它默认使用 ES 模块系统来打包和构建项目。如果需要在旧版浏览器(如 IE11)中运行项目,需要将代码转换为 ES5 语法。
要使用 Vite 打包成 ES5 语法,需要安装 @vitejs/plugin-legacy
插件。该插件将使用 babel 对你的代码进行转换,并生成两个版本的文件:一个现代浏览器版本,一个 ES5 版本。在 HTML 中,将会根据浏览器的 User Agent 来决定加载哪个版本的文件。
- 安装
@vitejs/plugin-legacy
js
npm install --save-dev @vitejs/plugin-legacy // es5打包
npm install --save-dev vite-plugin-top-level-await // 顶层await
- 在
vite.config.js
文件中添加插件配置:
js
import topLevelAwait from 'vite-plugin-top-level-await'
import legacy from '@vitejs/plugin-legacy';
...
plugins: [
topLevelAwait({
promiseExportName: '__tla',
promiseImportName: i => `__tla_${i}`
}),
legacy({
targets: ['defaults', 'not IE 11']
})
]
大部分项目到这就差不多能够完成了。
二、我碰到的问题
由于是很久之前的vite项目,我在接手他的时候还是vite2的版本,然后我就碰到了一个问题vite2.x版本和@vitejs/plugin-legacy 2.x
版本冲突了。 这里的解决方案是
- 升级vite版本到3.x
- 降低
@vitejs/plugin-legacy
版本到1.x
我一开始选择了降低插件版本,然后发现一个打包的bug有图片资源同名报错 The "fileName" or "name" properties of emitted files must be strings
然后我就选择升级vite版本到最新,升级到3.x,这里有个问题就是需要把其他vite相关的插件都升级到对应的版本,不然会报错。
升级到了vite3.x以后,由于我这个是多页面项目在vite.config.ts中修改了root配置项,导致我升级以后vite找不到.env文件了,后面经过我的尝试,我发现vite2.x版本一开始是会在root目录下面查找.env文件,找不到就vite.config目录下查找。
而vite3.x他就只在root中查找.env文件,因此才出现升级vite版本后找不到.env文件了。
我后面把.env环境变量文件放到了root所对应的文件夹下面就好了,我这里是放到了src下面。
js
export default defineConfig({
// 项目根目录
root: './src/', // root配置项
// 项目部署的基础路径
base: './',
// 静态资源服务文件夹
publicDir: 'public',
resolve: {
alias: {
'@/': `${path.resolve(__dirname, 'src')}/`
},
dedupe: [],
// 情景导出package.json 配置中的 exports 字段
conditions: [],
// 解析package.json 中的字段
mainFields: ['module', 'jsnext:main', 'jsnext'],
// 导入时想要省略的扩展名列表
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
},
// css: {
// preprocessorOptions: {
// scss: {
// additionalData: `@use "~/styles/theme/element-variables.scss" as *;`
// }
// }
// },
build: {
// 浏览器兼容性 'esnext' | 'modules'
target: 'esnext',
//输出路径
outDir: '../dist',
// 生成静态资源的存放路径
assetsDir: '../assets',
// 小于此阈值的导入或引用资源将内联为 base64 编码, 以避免额外的http请求, 设置为 0, 可以完全禁用此项,
assetsInlineLimit: 4096,
// 启动 / 禁用 CSS 代码拆分
cssCodeSplit: true,
// 构建后是否生成 soutrce map 文件
sourcemap: false,
// 自定义底层的 Rollup 打包配置
rollupOptions: {
// 引入 terser 插件
plugins: [terser({
format: {
comments: false, // 去除注释
},
})],
input: {
role: path.resolve(__dirname, 'src/index.html'),
login: path.resolve(__dirname, 'src/login.html'),
organization: path.resolve(__dirname, 'src/organization.html'),
class: path.resolve(__dirname, 'src/class.html'),
teacher: path.resolve(__dirname, 'src/teacher.html'),
resignedPersonnel: path.resolve(__dirname, 'src/resignedPersonnel.html'),
schoolCalendar: path.resolve(__dirname, 'src/schoolCalendar.html'),
lessonTimetable: path.resolve(__dirname, 'src/lessonTimetable.html'),
subject: path.resolve(__dirname, 'src/subject.html'),
task: path.resolve(__dirname, 'src/task.html'),
personage: path.resolve(__dirname, 'src/personage.html'),
report: path.resolve(__dirname, 'src/report.html'),
intelligentScheduling: path.resolve(__dirname, 'src/intelligentScheduling.html'),
myCurriculum: path.resolve(__dirname, 'src/myCurriculum.html'),
},
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]'
}
},
// @rollup/plugin-commonjs 插件的选项
commonjsOptions: {},
// 构建的库
// lib: { entry: string, name?: string, formats?: ('es' | 'cjs' | 'umd' | 'iife')[], fileName?: string },
// 当设置为 true, 构建后将会生成 manifest.json 文件
manifest: false,
// 设置为 false 可以禁用最小化混淆
// 或是用来指定是应用哪种混淆器
// boolean | 'terser' | 'esbuild'
minify: 'terser',
// 传递给 Terser 的更多 minify 选项
terserOptions: {},
// 设置为false 来禁用将构建好的文件写入磁盘
write: true,
// 默认情况下 若 outDir 在 root 目录下, 则 Vite 会在构建时清空该目录。
emptyOutDir: true,
// 启用 / 禁用 brotli 压缩大小报告
brotliSize: false,
// chunk 大小警告的限制
chunkSizeWarningLimit: 500
},
plugins: [
vue(),
ElementPlus({
useSource: true
}),
topLevelAwait({
promiseExportName: '__tla',
promiseImportName: i => `__tla_${i}`
}),
legacy({
targets: ['defaults', 'not IE 11']
})
],
server: {
host: '0.0.0.0',
port: 3030,
open: true
},
});