7
import "reflect-metadata"

function validate(target: any) {
  let paramtypes = Reflect.getMetadata("design:paramtypes", target);
  console.log(paramtypes);  // undefined
}

@validate
class Log {
  constructor(public readonly xx: string) {}
}

Hit me to start the server, and when I opened the webpage, I found that paramtypes was undefined

tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": false,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "include": ["./src"]
}
januw a
  • 2,056
  • 5
  • 18
  • 39

2 Answers2

11

Vite uses ESBuild which doesn't support "emitDecoratorMetadata" in tsconfig, since ESBuild doesn't have its own type system implemented. Refer to this vitejs/vite#788 for more details on this topic.

However, there are workarounds to this issue. One approach I took was explicitly disabling ESBuild and used SWC instead. You can find more details regarding that on this demo. Here is its vite config file:

import typescript from "@rollup/plugin-typescript";
import swc from "rollup-plugin-swc";

// import typescript from "rollup-plugin-typescript2";

export default defineConfig({
    plugins: [
        swc({
            jsc: {
                parser: {
                    syntax: "typescript",
                    // tsx: true, // If you use react
                    dynamicImport: true,
                    decorators: true,
                },
                target: "es2021",
                transform: {
                    decoratorMetadata: true,
                },
            },
        }),
    ],
    esbuild: false,
});

SWC is a fast alternative to ESBuild, having implemented its own type system, it can emit decorator metadata without any issue.

januw a
  • 2,056
  • 5
  • 18
  • 39
Zou Jeff
  • 785
  • 1
  • 6
  • 14
0

Using SWC is feasible solution, but if you want to stay closer to the original setup I've found the right configuration.

It's true that esbuild does not support decorator metadata, but! there is a community plugin for that - @anatine/esbuild-decorators.

I've added it to the optimizeBuild configuration and it Just Works™️.

From my understanding it shouldn't have worked after build (because from the docs vite does not use esbuild when building for prod), but it does work!

Here is an example repo with vite 4 & tsyringe that uses reflect-metadata https://stackblitz.com/edit/vitejs-vite-hzkjj3?file=vite.config.ts