Как разработчик Java, мир javascript был странным. Несмотря на то, что сам язык javascript был довольно простым, я просто не мог читать код, написанный другими. Сам язык развивался мучительно медленно, но его сторонняя экосистема была блестящей, они компенсировали недостатки языка и тем самым позволяли платформе идти в ногу с требованиями быстро развивающейся сети. Сторонние поставщики должны были использовать любую семантику, доступную для языка, чтобы добавить свои функциональные возможности или поведение. Это чаще всего приводило к тому, что код был совершенно нечитаемым, если только вы не являетесь рок-звездой javascript. С введением спецификации JavaScript ES6, также известной как ES2015, все изменилось — мы снова можем писать читаемый и тестируемый код!

Теперь вы могли реализовывать правильные концепции OOPS, используя ключевое слово new class, и разбивать свой код на модули, управлять областями переменных с помощью ключевых слов let/const и т. д. и т. д. Последней, но, безусловно, самой важной функцией, которую я с нетерпением ждал, была зависимость. инъекции, которая также теперь возможна с помощью декораторов javascript с помощью плагина https://www.npmjs.com/package/dependency-injection-es6. Мир javascript больше не будет прежним.

К сожалению, на момент написания этой статьи поддержка ES6 не является 100%, поэтому вам нужно полагаться на полные заполнения и транспиляторы, такие как Babel. В этой статье мы создадим базовую настройку для использования Babel, чтобы создать настройку, в которой вы сможете начать писать красивый объектно-ориентированный код для NodeJS.

Если у вас нет времени проходить всю статью, вы можете просто клонировать https://github.com/sangith/babel-nodejs-ioc-setup/ и начать взламывать.

  1. Сначала вам нужно настроить зависимости babel в вашем package.json.
"devDependencies": {
"babel-cli": "^7.0.0-beta",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^7.0.0-beta",
"babel-preset-es2016": "^7.0.0-beta",
"babel-preset-es2017": "^7.0.0-beta",
"babel-preset-stage-2": "^7.0.0-beta",
"babel-register": "^7.0.0-beta"
},
"dependencies": {
"dependency-injection-es6": "^1.2.1"
}

2. Настройте файл `.babelrc` следующим образом (создайте, если он не существует). Обратите внимание, что я настроил версию узла 9.3.0. Пожалуйста, измените версию вашего узла

{
"presets": [
    ["env", {
      "targets": {
        "node": "9.3.0"
      }
    }]
  ],
"plugins": ["transform-decorators-legacy","transform-class-properties"]
}

3. запустите `npm install`, чтобы модули вашего узла были загружены

4. создайте файл с именем `dev` (без расширения) и добавьте следующее содержимое. Это файл, который вы будете запускать из командной строки, чтобы запустить приложение в режиме разработки. Вы можете изменить index на любое имя вашего файла приложения, я использую index.js

require('babel-register')
require('./index')

5. Вот и все, у вас есть базовые настройки. Вот пример внедрения зависимостей. У меня есть интерфейс с именем MessageService, который реализован EmailService и SMSService. В зависимости от ваших требований вы можете динамически привязывать реализацию.

MessageService.js

export class MessageService {
sendMessage(msg){}
}

EmailService.js (обратите внимание на использование импорта, наследования, одноэлементного оформления)

import {singleton} from 'dependency-injection-es6';
import {MessageService} from './MessageService';
 
@singleton
export class EmailService extends MessageService {
    constructor(){
     console.info("Email constructor");
      super();
    }
    sendMessage(msg){
        console.info("Email Message sent from EmailService");
       
    }
}

index.js

"use strict";
import {singleton,container,inject} from 'dependency-injection-es6';
import {MessageService} from './MessageService';
import {EmailService} from './EmailService';
class MyApplication {
 
    @inject(MessageService)
    service;
  
    constructor(){
        console.info("will be injected",this.service);
    }
}
/* do binding */
container.bind(MessageService,EmailService);
/* Instantiate the app .. and see what is getting injected */
container.resolve(MyApplication);

Чтобы запустить ваш пример run node dev , вы должны увидеть, что EmailService внедряется.