You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 15:54:58