Inversify не может внедрить класс с зависимостями - PullRequest
2 голосов
/ 15 апреля 2020

Я запустил новый проект машинописи, основанный на старом проекте MIME (который начинался как обычный javascript), и я не могу заставить работать нетривиальные инъекции. Я ничего не знаю о конфигурации babel (из-за того, что смотрю с create-реагировать на приложение). Я попробовал рекомендуемый компиляторOptions , и он тоже не сработал ..... мои настройки могут быть беспорядочными, но так они развивались.

Не стесняйтесь получить весь проект от 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'));

пакет. 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"
    ]
}

config-overrides. js

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

module.exports = override(
);

Отладка

Я попытался отладить проблему, но нашел немного. Нет метаданных, не делается попытка разобрать Function.prototype.toString (), как в этот ответ . Что-то не так с моей конфигурацией, но эта штука довольно непрозрачна для меня.

Ответы [ 2 ]

3 голосов
/ 23 апреля 2020

Вы боретесь из-за того, что конфигурация реагирования 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;

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

//...

Решение основано на этом:

Подробнее о том, почему декораторы не поддерживаются:

1 голос
/ 24 апреля 2020

У меня было то же решение, что и опубликовано , но вместо package.json я использовал config-overrides.js:

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

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

Если честно, мне не понравилось это решение так что я не опубликовал это ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...