0

我显然误解了 TSyringe 应该如何解决具有依赖关系的类。

我创建了一个最小的复制。在我的 index.tsx 中,我按照文档和 import 中的指示进行操作reflect-metadata。如果我注入一个singleton没有依赖项的类,则此示例有效:

// index.tsx
import "reflect-metadata";
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />,  document.getElementById('root'));

一个单例类:

// _A.ts
import {inject, singleton} from 'tsyringe';

@singleton()
export class A {    
    get_msg() {
        return "Worked!";
    }
}

以及使用它的组件:

// App.tsx
import React from 'react';
import './App.css';
import {container} from "tsyringe";
import {A} from "./_A";

interface Props {
  a?: A
}

function App({a = container.resolve(A)}: Props) {
  return (
    <div className="App">
          {a.get_msg()}
    </div>
  );
}

export default App;

当我运行应用程序时,Worked!文本按预期打印。

但是,如果我创建第二个名为 B 的单例:

// _B.ts
import {singleton} from 'tsyringe';

@singleton()
export class B {
    get_msg() {
        return "Worked!";
    }
}

然后注入BA获取消息:

// _A.ts
import {inject, singleton} from 'tsyringe';
import {B} from "./_B";

@singleton()
export class _A {
    constructor(private b: B) {
    }

    get_msg() {
        return this.b.get_msg();
    }
}

然后它失败了Uncaught Error: TypeInfo not known for "A"

我有:

"experimentalDecorators": true,
"emitDecoratorMetadata": true,

在我的tsconfig.ts,正如他们在自述文件中指出的那样。

注射器不应该自动解析 B,将 B 注入 A,然后将 A 注入我的应用程序组件,以便我可以打印消息吗?

我错过了什么?

4

1 回答 1

0

好的,所以我想通了。

为了保留 typescript 元数据并允许 reflect-metadata 做它的事情,我们需要添加babel-plugin-transform-typescript-metadata到项目中。

但是,为了自定义 create-react-app,您需要该craco库。那里有几个,但 craco 是我唯一能支持 CRA 4.x 的。您不能使用最新的(CRA 5.0),因为这些库都不支持它。

所以:

1 - 安装 Craco 并进行设置。

2 -babel-plugin-transform-typescript-metadata作为开发依赖安装

3 - 将craco.config.js文件添加到您的项目以加载此插件:

module.exports = function ({ env: _env }) {
    return {
        babel: {
            plugins: [
                "babel-plugin-transform-typescript-metadata"
            ]
        },
    };
};

4 - 确保更新您的 package.json 以使用 craco 启动,以便进行配置覆盖:

  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject"
  },

就是这样,它现在可以工作了。希望它可以帮助那里的人。

于 2022-02-07T16:00:19.547 回答