vite构建js库兼容传统浏览器
在搭建 js 库的时候,想着能不能也兼容下传统浏览器,于是研究了下,大致步骤是这样的,需要借助 Babel 及相关的插件来解决。
1、安装相关依赖
npm install --save-dev @babel/core @babel/preset-env @rollup/plugin-babel
2
2、配置,创建 babel.config.js 文件,配置如下:
module.exports = {
presets: [
['@babel/preset-env', {
targets: {
browsers: ['> 1%', 'last 20 versions', 'ie >= 11'],
},
useBuiltIns: 'usage',
corejs: 3,
}],
],
};
2
3
4
5
6
7
8
9
10
11
3、在 vite.config.js 中配置 Babel 插件,让 Vite 在构建过程中使用 Babel 将代码转换为 ES5
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import babel from '@rollup/plugin-babel';
export default defineConfig({
plugins: [
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
extensions: ['.js', '.ts'],
}),
],
build: {
target: ['es2015'],
rollupOptions: {
output: {
format: 'cjs',
},
},
},
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
配置完成,执行打包时,报错了,类似这种, module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension。
于是,将 babel.config.js 文件的后缀名改成.cjs,及 babel.config.cjs,再执行打包后正常了。
查看打包后的文件,发现 promise 并没有被转换,因为 Babel 默认只处理语法转换,不会自动引入 polyfill。
解决方案:手动引入 polyfill
1、安装 core-js 和 regenerator-runtime
npm install --save core-js regenerator-runtime
2、如果 babel.config.cjs 中设置了 useBuiltIns: 'entry',则需要在入口文件中引入 polyfill
import 'core-js/stable';
import 'regenerator-runtime/runtime';
2
ps: babel.config.cjs 中的 useBuiltIns 有两种取值,usage 和 entry
区别:
当 useBuiltIns 设置为 'usage' 时,Babel 会根据代码中实际使用的 API 和目标浏览器的支持情况自动引入必要的 polyfill
useBuiltIns: 'entry' 时,Babel 不会根据实际使用的 API 自动引入 polyfill,而是需要在项目的入口文件中手动引入所需的 polyfill
实践证明,使用 useBuiltIns: 'entry' 时,打包出来的体积偏大,建议使用 useBuiltIns: 'usage'