如何避免Vite对JavaScript文件中的类字段进行转换?
如何避免Vite将类字段转换为__publicField调用?
问题描述
我基于Vite开发项目,定义了如下类:
class Actor extends ActorBase { system; constructor(...) { super(...); ... } ... }
构建后代码被自动转换为:
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class Actor extends ActorBase { constructor(...) { super(...); __publicField(this, "system"); ... } ... }
这种转换导致代码与FoundryVTT的内部机制冲突,字段无法正确初始化,请问如何阻止该转换?
背景
我正在开发FoundryVTT虚拟桌面的扩展插件,__publicField(...)的类字段定义方式与FoundryVTT不兼容,引发了初始化异常。
已尝试方案
- 调整
jsconfig.json的useDefineForClassFields配置,设为true或false均无效果 - 修改
target配置无法阻止转换 - 尝试用
system = super.system初始化类字段,同样与FoundryVTT行为冲突
配置文件
vite.config.js
import { defineConfig } from 'vite' import copy from "rollup-plugin-copy"; import { svelte } from '@sveltejs/vite-plugin-svelte' import path from 'path'; export default defineConfig({ resolve: { alias: {...}, }, build: { outDir: 'dist', emptyOutDir: true, minify: false, lib: { name: 'animabf', entry: 'src/animabf.mjs', formats: ['es'], }, rollupOptions: { output: { preserveModules: true, preserveModulesRoot: "src", entryFileNames: ({ name: fileName }) => { return `${fileName}.js` }, assetFileNames: 'animabf.[ext]' } } }, plugins: [ svelte(), copy({...}) ], })
jsconfig.json
{ "compilerOptions": { "target": "ESNext", "useDefineForClassFields": false, "lib": ["dom", "dom.iterable", "esnext"], "types": ["svelte", "@types/jest", "@league-of-foundry-developers/foundry-vtt-types"], "paths": { ... }, "moduleResolution": "node", "resolveJsonModule": true, "esModuleInterop": true, "allowJs": true, "checkJs": true, "strict": true, "strictNullChecks": true, "skipLibCheck": true, "outDir": "dist" }, "include": ["src"], "exclude": ["./**/.*.test.*", "./**/__mocks__", "node_modules"] }
解决方案
1. 指定ESBuild目标为支持原生类字段的版本
Vite默认用ESBuild处理代码转换,将build.target设为ES2022或更高版本(原生支持类字段),ESBuild就不会生成__publicField转换代码。修改vite.config.js的build配置:
build: { // 保留原有配置 target: 'ES2022', // ... }
2. 强制ESBuild启用原生类字段支持
如果指定target无效,可直接配置ESBuild声明目标环境支持类字段:
export default defineConfig({ // 保留原有配置 esbuild: { supported: { 'class-fields': true } }, // ... })
3. 排查额外Rollup插件的转换逻辑
如果项目中使用了Babel等额外Rollup插件,需确保这些插件未开启类字段转换逻辑,避免覆盖Vite的配置。
4. 手动在构造函数中初始化字段(备选)
若上述配置均无效,可放弃类字段声明语法,改用构造函数内直接赋值:
class Actor extends ActorBase { constructor(...) { super(...); this.system = undefined; // 或根据Foundry逻辑赋值 ... } ... }
这种写法不会触发__publicField转换,同时兼容FoundryVTT机制。
内容的提问来源于stack exchange,提问作者Aitor B
相关产品推荐
相关产品推荐

