Inversify.js - Reflect.hasOwnMetadata is not a fun

2019-06-15 00:20发布

问题:

I'm trying out Inversify.js for a Typescript application I'm using. Right now, there is no framework involved, so it's pure ES2015.

I'm trying to follow along the example in the main page, but I'm being hit with: "Reflect.hasOwnMetadata is not a function" when I try to run it in the browser.

I'm using Webpack as package bundler.

Here is my folder structure:

Here is the main app.ts file:

/// <reference path="../typings/index.d.ts" />
/// <reference path="./domain/abstract/match.interface.ts" />

import kernel from "../inversify/inversify.config.ts";

import {symbols} from "../inversify/symbols.ts";

var ninja = kernel.get<INinja>("INinja");

ninja.fight();
ninja.sneak();

interfaces.d.ts:

interface INinja {
    fight(): string;
    sneak(): string;
}

interface IKatana {
    hit(): string;
}

interface IShuriken {
    throw();
}

inversify.config.ts

/// <reference path="../node_modules/inversify/type_definitions/inversify/inversify.d.ts" />
/// <reference path="../node_modules/reflect-metadata/reflect-metadata.d.ts" />
/// <reference path="inversify.ts" />

import {Kernel} from "inversify"
//import {MatchHub} from "../app/components/Hubs/match/match-hub.component.ts";
//import {symbols} from "./symbols.ts";


import {Ninja, Katana, Shuriken} from "./inversify.ts";


var kernel = new Kernel();
kernel.bind<INinja>("INinja").to(Ninja);
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IShuriken>("IShuriken").to(Shuriken);


export default kernel;

symbols.ts:

export const symbols = {
    Match : Symbol("Match")
}

tsconfig.json:

{
  "compilerOptions": {
    "noImplicitAny": false,
    "experimentalDecorators": true,
    "emitDecoratorMetadata":  true, 
    "removeComments": true,
    "sourceMap": true,
    "target": "es5"
  },
  "exclude": [
    "node_modules",
    "bower_components",
    "wwwroot"
  ]
}

Webpack.config.js:

module.exports = {
  entry: './app/app.ts',
  output: {
    filename: '../Scripts/app/app.js'
  },
  resolve: {
      extensions: ['', '.Webpack.js', '.web.js', '.ts','.js', '.tsx']
  },
  module: {
    loaders: [
        {
          test: /\.ts?$/,
          exclude: /(node_modules|bower_components)/,
          loader: 'ts-loader'
        }
    ]
  },
  watch: true
}

Firefox Console Error:

Webpack output:

When I tried to install Inversify the following warnings popped up:

Is it a bug? Or am I doing something wrong? Thanks!

PS: Tried following the sample files, but I couldn't understand anything!

I come from ASP.NET MVC 5 with Ninject so I can relate for most of the syntax.

回答1:

It seems you will need to include the reflect-metadata package. Try adding an import to it in inversify.config.ts by doing:

import "reflect-metadata";


回答2:

May be a silly thing to point out, I ran into a the same issue but it was because of the order of imports. Its unlikely to be the case for any other imports but in case of reflect-metadata it has to be imported before any classes that use it.

import { Container } from "inversify";
//reflect-metadata should be imported 
//before any interface or other imports
//also it should be imported only once
//so that a singleton is created.
import "reflect-metadata";
import Battle from "./interfaces/battle";
import EpicBattle from "./interfaces/epic_battle";