簡體   English   中英

Inversify 無法注入 class 依賴項

[英]Inversify cannot inject class with dependencies

我開始了一個新的 typescript 項目,該項目基於一個舊的 mime 項目(以普通 javascript 開始),但我無法進行任何重要的注入工作。 我對 babel 配置一無所知(因為盯着 create-react-app)。 我嘗試了推薦的 compilerOptions ,但它也沒有用.....我的設置可能一團糟,但這就是它的演變方式。

隨意從github獲取整個項目(獲取並運行npm install && npm start )或繼續閱讀。

import 'reflect-metadata';
import { Container } from 'inversify';
import React from 'react';
import ReactDOM from 'react-dom';
import { injectable } from 'inversify';

@injectable()
export class Simple {
}

@injectable()
export class Composed {
    simple: Simple;

    // ERROR: Module parse failed: Unexpected character '@'
    // constructor(@inject simple: Simple) {
    //  this.simple = simple;
    // }

    // Error: Missing required @inject or @multiInject annotation in: argument 0 in class Composed.
    constructor(simple: Simple) {
        this.simple = simple;
    }
}

const container = new Container();
container.bind(Simple).toSelf();
container.bind(Composed).toSelf();
console.log(container.get(Composed));

function Main() {
    return <div>
        {JSON.stringify(container.get(Composed))}
    </div>;
}

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

package.json

{
    "name": "inversify-problem",
    "version": "0.0.1",
    "description": "",
    "private": true,
    "dependencies": {
        "@material-ui/core": "^4.9.8",
        "@material-ui/icons": "^4.9.1",
        "array.prototype.flatmap": "^1.2.3",
        "customize-cra": "^0.9.1",
        "deep-equal": "^2.0.1",
        "eslint": "^6.8.0",
        "inversify": "^5.0.1",
        "json-stable-stringify": "^1.0.1",
        "mobx": "^5.15.4",
        "mobx-decorators": "^6.0.1",
        "mobx-react": "^6.1.8",
        "mobx-state-tree": "^3.15.0",
        "notistack": "^0.9.9",
        "react": "^16.13.1",
        "react-app-polyfill": "^1.0.6",
        "react-app-rewire-mobx": "^1.0.9",
        "react-app-rewired": "^2.1.5",
        "react-dom": "^16.13.1",
        "reflect-metadata": "^0.1.13",
        "resize-observer-polyfill": "^1.5.1",
        "shallowequal": "^1.1.0",
        "styled-components": "^5.0.1",
        "ts-enum-util": "^4.0.1"
    },
    "devDependencies": {
        "babel-plugin-import": "^1.13.0",
        "babel-plugin-styled-components": "^1.10.7",
        "@types/classnames": "^2.2.10",
        "@types/deep-equal": "^1.0.1",
        "@types/json-stable-stringify": "^1.0.32",
        "@types/jest": "^25.1.4",
        "@types/node": "^13.9.8",
        "@types/react": "^16.9.29",
        "@types/react-dom": "^16.9.5",
        "eslint-plugin-unused-imports": "^0.1.2",
        "tslint-etc": "^1.10.1",
        "react-scripts": "^3.4.1",
        "typescript": "^3.8.3"
    },
    "scripts": {
        "start": "react-app-rewired start",
        "build": "react-app-rewired build",
        "test": "react-app-rewired test",
        "eslint": "eslint --fix $(find src -name '*.ts' -o  -name '*.tsx')",
        "eject": "react-scripts eject"
    },
    "eslintConfig": {
        "extends": "react-app",
        "parserOptions": {
            "ecmaFeatures": {
                "legacyDecorators": true
            }
        }
    },
    "browserslist": [
        ">0.2%",
        "not dead",
        "not ie <= 11",
        "not op_mini all"
    ]
}

tsconfig.json

{
    "compilerOptions": {
        "target": "ES5",
        "sourceMap": true,
        "downlevelIteration": true,
        "importHelpers": true,
        "lib": [
            "dom",
            "dom.iterable",
            "esnext",
            "es6",
            "webworker",
            "es2015.collection",
            "es2015.iterable",
            "es2019"
        ],
        "types": [
            "node",
            "reflect-metadata"
        ],
        "allowJs": false,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "strictNullChecks": true,
        "forceConsistentCasingInFileNames": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "noImplicitAny": true,
        "noEmitOnError": false,
        "incremental": false,
        "jsx": "preserve",
        "noEmit": true
    },
    "include": [
        "src/index.tsx",
        "src/mg/extras.d.ts"
    ]
}

配置覆蓋.js

const {
    override,
} = require("customize-cra");

module.exports = override(
);

調試

我試圖調試問題,但發現不多。 沒有元數據,沒有像這個答案那樣嘗試解析 Function.prototype.toString() 。 我的配置有問題,但那件事對我來說很不透明。

你正在掙扎,因為 react babel 配置不允許裝飾器,所以你可以做的是:

$ npm run eject
$ npm install react-scripts # if you use an older npm installation then you need to add --save
$ npm install -D @babel/plugin-proposal-decorators 
$ npm install -D babel-plugin-parameter-decorator

你的package.json現在擴展了很多選項,找到babel部分並更改如下:

  "babel": {
    "plugins": [
      [
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        "babel-plugin-parameter-decorator"
      ]
    ],
    "presets": [
      // ...
      ["@babel/preset-typescript", { "onlyRemoveTypeImports": true }]
    ]
  }

現在您至少可以按如下方式使用字段注入:

// ...
import { inject, injectable } from 'inversify';
// ...

@injectable()
class Composed {
    private readonly simple: Simple;

    public constructor(@inject(Simple) simple: Simple) {
        this.simple = simple;
    }
}

//...

解決方案基於此:

有關為什么不支持裝飾器的更多信息:

我有與發布的相同的解決方案,但我沒有使用package.json ,而是使用了config-overrides.js

const {
  override,
  addDecoratorsLegacy,
  addBabelPlugin,
} = require("customize-cra");

module.exports = override(
  addDecoratorsLegacy(),
  addBabelPlugin("babel-plugin-parameter-decorator")
);

老實說,我不喜歡這個解決方案,所以我沒有發布它......

暫無
暫無

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

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