簡體   English   中英

使用 tsyringe 與 TypeScript 進行依賴注入反應

[英]React with TypeScript using tsyringe for dependency injection

我目前在使用 React TypeScript 項目時遇到問題。

我使用npx create-react-app my-app --template typescript創建了我的項目。

我最近為依賴注入添加了 tsyringe,並試圖為 apiService 實現它。 在按照自述文件( https://github.com/microsoft/tsyringe#injecting-primitive-values-named-injection )添加原始值后,我遇到了障礙。 我已經將experimentalDecoratorsemitDecoratorMetadata添加到我的tsconfig.json文件,但沒有成功。

我遇到的錯誤實際錯誤是:

./src/ts/utils/NetworkService.ts 9:14
Module parse failed: Unexpected character '@' (9:14)
File was processed with these loaders:
 * ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
 * ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| 
| let NetworkService = (_dec = singleton(), _dec(_class = (_temp = class NetworkService {
>   constructor(@inject('SpecialString')
|   value) {
|     this.str = void 0;

我相當確定這個問題是由 Babel 引起的,但是我使用 npm create react-app --template typescript 創建了這個並且似乎無法訪問 Babel 配置。

網絡服務.ts

@singleton()
export default class NetworkService
{

    private str: string;
    constructor(@inject('SpecialString') value: string) {
        this.str = value;
    }
}

調用方法

bob() 
{
    const inst = container.resolve(NetworkService);
}

在 index.ts 中注冊 Class

container.register('SpecialString', {useValue: 'https://myme.test'});


@registry([
    { token: NetworkService, useClass: NetworkService },
])
class RegisterService{}

React-Scripts 管理與項目相關的許多配置。 在許多情況下,這很好,實際上是一個不錯的功能。 但是,因為 React-Scripts 使用 Babel 作為其開發環境並且不公開配置。

您必須運行npm run eject以公開配置。

請注意,這是一種單向操作,無法撤消。 就個人而言,我更喜歡對我的配置進行更多控制。

之后,您可以在新創建的配置文件夾中編輯webpack.config.js

dev-environment找到babel-loader相關的部分,並將'babel-plugin-transform-typescript-metadata'添加到plugins array中。

您可以使用“覆蓋”您的某些參數的庫,而不是彈出。

我用過 craco: https://www.npmjs.com/package/@craco/craco

擴展 Jordan Schnur 的回復,以下是我在將 TSyringe 添加到我的 CRA 應用程序時遇到的更多陷阱:

將導入類型與 @inject 一起使用

如果您收到此錯誤“TS1272:在啟用 'isolatedModules' 和 'emitDecoratorMetadata' 時,必須使用 'import type' 或命名空間導入來導入修飾簽名中引用的類型。” 對於有問題的進口,用import type替換import 使用@inject時會遇到這種情況,例如將import { IConfig } from "iconfig"替換為import type { IConfig } from "iconfig"

修復笑話

您的 Jest 測試也會因 TSyringe 而中斷,尤其是在使用@inject時。 我收到錯誤“Jest 遇到了意外的令牌”,詳細信息constructor(@((0, _tsyringe.inject)("")) (“@”標記為有問題的令牌)。我采取了以下步驟在 CRA 中修復該問題:

添加行import "reflect-metadata"; 到文件src/setupTests.ts的頂部

config/jest/babelTransform.js替換第 18 行及以下內容:

    
    module.exports = babelJest.createTransformer({
      presets: [
        [
          require.resolve('babel-preset-react-app'),
          {
            runtime: hasJsxRuntime ? 'automatic' : 'classic',
          },
        ],
      ],
      babelrc: false,
      configFile: false,
    });
    

至:

    
    module.exports = babelJest.createTransformer({
      presets: [
        [
          require.resolve('babel-preset-react-app'),
          {
            runtime: hasJsxRuntime ? 'automatic' : 'classic',
          },
        ],
      ],
      plugins: [
        require.resolve('babel-plugin-transform-typescript-metadata')
      ],
      babelrc: false,
      configFile: false,
    });
    

我創建了一個更簡單的 DI 庫,它不需要裝飾器或 polyfill。 像魅力一樣與 CRA 一起工作,並具有很酷的 React 綁定

iti

import { useContainer } from "./_containers/main-app"

function Profile() {
  const [auth, authErr] = useContainer().auth

  if (authErr) return <div>failed to load</div>
  if (!auth) return <div>loading...</div>

  return <div>hello {auth.profile.name}!</div>
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM