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

问题描述

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