Повторное включение модуля на лету

В настоящее время я работаю над техническим долгом, выявленным SonarQube для приложения Node.js. Мое приложение позволяет на лету переключаться между живым и фиктивным источником данных. Для этого я удаляю предыдущее «требование» из кеша и повторно требую его. При запуске SonarQube ему не нравятся операторы «требовать». Он предлагает операторы «импорта». Однако в данном случае это может не подойти.

Упрощенная версия существующего кода:

var config = require('../config');
var polService = require(config.polService);
var root = require('../root');
function doingStuff(liveOrMock) {
    setEnvironment(liveOrMock);
    delete require.cache[require.resolve(root.path + ‘/config’)];
    config = require('../config');
    polService = require(config.polService);
}

Функция setEnvironment устанавливает process.env.NODE_ENV = liveOrMock, который используется в config.js. Мы экспортируем модуль config, используя module.exports = localOptions[process.env.NODE_ENV];. Этот код выбирает одну пару ключей из JSON. Возвращаемое значение используется для выбора того, какой модуль используется для restService.

Возможность изменить используемый модуль для polService является целью кода.


person David Stewart    schedule 13.06.2017    source источник
comment
Да, похоже модули ES6 здесь не подходят. Они не разрешают так возиться.   -  person Bergi    schedule 13.06.2017


Ответы (1)


Измените свой модуль config, чтобы экспортировать функцию, а затем вызывайте эту функцию всякий раз, когда вам нужно изменить среду.

Чтобы сделать polService динамическим модулем, вы можете использовать динамический import(). import() изначально не поддерживается, но вы можете использовать этот плагин Babel ( он работает с веб-пакетом), чтобы транспилировать его.

config.js:

export default () => {
  // ...
  return localOptions[process.env.NODE_ENV];
}

Основной модуль:

import getConfig from '../config';

let config = getConfig();

function doingStuff(liveOrMock) {
  setEnvironment(liveOrMock);
  config = getConfig();
  return import(config.polService).then(result => {
    polService = result;
  });
}

Имейте в виду, что теперь функция doingStuff является асинхронной (то есть возвращает промис), поэтому вы не можете просто вызвать ее и получить доступ к polService немедленно. Вы должны дождаться его, используя then() или используя await в асинхронная функция.

Если у вас ограниченное количество модулей polService, может быть лучше импортировать их все заранее, а в функции doingStuff просто переключиться, к какому из них относится переменная polService.

import getConfig from '../config';
import polService1 from '../polService1';
import polService2 from '../polService2';
import polService3 from '../polService3';

const polServices = { polService1, polService2, polService3 };

let config = getConfig();
let polService = polService1;

function doingStuff(liveOrMock) {
  setEnvironment(liveOrMock);
  config = getConfig();
  polService = polServices[config.polService];
}
person Michał Perłakowski    schedule 13.06.2017