![](/img/trans.png)
[英]React/TypeScript Dynamic Switch Statement using Dependency Injection
[英]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 )添加原始值后,我遇到了障碍。 我已经将experimentalDecorators和emitDecoratorMetadata添加到我的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 应用程序时遇到的更多陷阱:
如果您收到此错误“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 绑定
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.