为什么在vite中不能使用reflect-metadata

Why can't reflect-metadata be used in vite

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) {}
}

打我启动服务器,打开网页发现paramtypes未定义

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"]
}

Vite 在 tsconfig 中使用不支持 "emitDecoratorMetadata" 的 ESBuild,因为 ESBuild 没有实现自己的类型系统。有关此主题的更多详细信息,请参阅此 vitejs/vite#788

不过,这个问题有一些解决方法。我采用的一种方法是明确禁用 ESBuild 并改用 SWC。您可以在 this demo 上找到有关该内容的更多详细信息。这是它的 vite 配置文件:

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 是 ESBuild 的快速替代品,实现了自己的类型系统,它可以毫无问题地发出装饰器元数据。