问题出现原因
Object.hasOwn 是 ECMAScript 2022(也称为 ES13 或 ES2022)引入的一个新方法。它用于检查对象是否具有某个自身属性,而不检查其原型链上的属性。版本太低找不到这个方法
第一种方案:单独加Polyfill
// Polyfill for Object.hasOwn for older browsers
if (!Object.hasOwn) {
Object.defineProperty(Object, 'hasOwn', {
value(object: object, key: string | symbol): boolean {
return Object.prototype.hasOwnProperty.call(object, key)
},
configurable: true,
enumerable: false,
writable: true,
})
}
单独为这个加一下,以最小代码改动
第二种:引入所有的兼容Polyfill
npm install vite-plugin-babel @babel/preset-env core-js -D
or
pnpm install vite-plugin-babel @babel/preset-env core-js -D
配置
import react from '@vitejs/plugin-react';
import * as path from 'node:path';
import { defineConfig } from 'vite';
import VitePluginBabel from 'vite-plugin-babel';
export default defineConfig(({ mode }) => {
const outDir = mode === 'production' ? 'build' : 'test-build';
return {
plugins: [
react(),
VitePluginBabel({
babelConfig: {
presets: [
[
'@babel/preset-env',
{
targets: '> 0.25%, not dead',
useBuiltIns: 'entry',
corejs: 3,
},
],
],
},
}),
],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
build: {
outDir,
},
};
});
入口文件引入
import 'core-js/stable';
// 你的其他入口代码
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
ReactDOM.createRoot(document.getElementById('root')!).render(
<App />
);
自己校验下低版本有无其他问题
第三种:直接打包输出ES6或者更低
// vite.config.ts
import react from '@vitejs/plugin-react';
import * as path from 'node:path';
import { defineConfig } from 'vite';
export default defineConfig(({ mode }) => {
const outDir = mode === 'production' ? 'build' : 'test-build';
return {
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
build: {
outDir,
target: 'es6', // 输出 ES6 代码
},
};
});
简单对比
| 特性 | 使用 Polyfill | 直接输出 ES6 代码 |
|---|---|---|
| 兼容性 | 提供更广泛的浏览器兼容性 | 仅限于支持 ES6 的现代浏览器 |
| 构建配置 | 需要配置 Babel 和 Polyfill | 配置 Vite 的 build.target 为 es2016或更低 |
| 打包体积 | 较大,包含 Polyfill 代码 | 较小,不包含 Polyfill 代码 |
| 运行时性能 | 可能稍慢,由于 Polyfill 的运行时开销 | 较快,没有 Polyfill 的运行时开销 |
| 开发复杂度 | 需要了解并配置 Polyfill | 相对简单,只需配置目标版本 |
| 代码现代性 | 可以使用现代 JavaScript 特性,但需要 Polyfill | 直接使用现代 JavaScript 特性 |
| 维护性 | 需要定期更新 Polyfill | 主要依赖于浏览器的更新 |
需要注意的是兼容越狠,意味着打包出来的代码越多,按需采纳吧