I have a project using Vite (below you can see the vite.config.js
file and the jsconfig.json
in case it matters), and I am facing the following problem. I have a class defined like
class Actor extends ActorBase {
system;
constructor (...) {
super(...)
...
}
...
}
When building, it gets transformed into something like
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");
...
}
...
}
Is it possible to avoid this transformation?
The code I'm working on is to be consumed by a web app (it's some sort of extension/plugin for that app). In particular, it is a system for the virtual tabletop FoundryVtt.
This way of defining the class field with __publicField(...)
clashes with the web app consuming the code (FoundryVtt), and avoids the correct initialisation of the field for some reason I don't understand but must have something to do with the internals of FoundryVtt.
I thought it had something to do with the config "useDefineForClassField" in the jsconfig.json
, but I tried to set it both to true
and false
with no difference. Setting different values for the target won't avoid it either.
I have also tried to initialise the value of the class field by using system = super.system
but that way also conflicts with the web app (FoundryVtt) behaviour.
// 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"]
}
Changing jsconfig.json
shouldn't affect the compilation here -- it is used by the language server or by svelte-check
only.
Adding a more modern target (which doesn't need the polyfill) to vite.config.js
works for me! That is:
export default defineConfig({
...,
build: {
target: 'esnext',
...
}
});