Подтвердить что ты не робот

TypeScript - импорт/экспорт условного модуля

TypeScripts абстрагирует модуль импорта/экспорта в виде "декларативного" способа.

Но что, если я хочу импортировать или экспортировать что-то на основе какого-то определенного времени выполнения?

Наиболее распространенным вариантом использования является обмен кодами между платформами типа Node.js и Windows Script Host.

TypeScript очень собственный io.ts, который абстрагирует ввод/вывод в компиляторе TSC, вручную взламывает встроенный синтаксис модуля TypeScript. Это единственный способ?

P.S. Проблема с приложением import fs = module ( "fs" ) в оператор if заключается в том, что TypeScript разрешает только операции импорта на верхнем уровне. Это означает, что в WSH требуется ( "fs" ) будет выполняться и, очевидно, не выполняется, поскольку требуется undefined.

4b9b3361

Ответ 1

Я согласен, что тот факт, что у них может быть только область охвата, в лучшем случае субоптимальна. Помимо проблемы, о которой вы говорили, это также означает более медленное время начальной загрузки программного обеспечения. Например, внутри nodejs я иногда иногда загружаю модуль в функцию, если эта функция редко используется. Поэтому мое приложение запускается быстрее, так как оно еще не загружает этот модуль.

И, конечно, вы можете напрямую использовать требование или AMD, но вы не упустите некоторые из преимуществ ввода.

Я думаю, однако, что реальная проблема заключается в том, что гармонии /es 6 определены модули, которые должны быть заполнены, и TS, похоже, следует этому предложению. Поэтому не уверен, сколько TS команда может сделать, не получая от стандартного органа.

Ответ 2

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

Имейте экспорт, который всегда испускается, но изменяйте содержимое в зависимости от значения времени выполнения. Например:.

// outputModule.ts
export const priv = (process.env.BUILD_MODE === 'test')
  ? { hydrateRecords, fillBlanks, extractHeaders }
  : null

Затем в загружаемом файле импортируйте экспорт, убедитесь, что импортированное значение существует, и если это так, назначьте все значения, которые вы в противном случае импортировали отдельно для набора переменных:

// importingModule.spec.ts
import { priv } from './outputModule';

const { hydrateRecords, fillBlanks, extractHeaders } = priv as any;
// these will exist if environment var BUILD_MODE==='test'

Ограничения:

  • Вам, к сожалению, нужно установить импорт в "any", чтобы сделать компилятор счастливым.
  • Вам нужно проверить, определены ли определенные импортные данные (но это происходит с территорией).
  • Импортирующий файл ожидает, что значения будут определены. Таким образом, вам необходимо убедиться, что для импорта файлов необходимы модули (это нормально, если вы имеете дело с файлами, которые запускаются только во время тестирования), или вам придется определять альтернативные значения для случаев, когда они фактически не экспортируются.

Тем не менее, это сработало очень хорошо для меня в моих целях, надеюсь, это сработает и для вас. Это особенно полезно для частного тестирования частных методов.

Ответ 3

Существует механизм динамического импорта в TypeScript, хотя реализация отличается в зависимости от типа модуля.

Пример ниже (для AMD) будет условно загружать модуль:

declare function require(moduleNames: string[], onLoad: (...args: any[]) => void): void;

import * as ModuleAlias from './mod';

const someCondition = true;

if (someCondition) {
    require(["./mod"], (module: typeof ModuleAlias) => {
        console.log(module.go());
    });
}

Оператор import в верхней части файла является инертным, и фактическая загрузка модуля не произойдет, если условие if (someCondition) истинно.

Вы можете проверить это, изменив someCondition и увидев влияние на вкладку сети, или вы можете посмотреть сгенерированный код... в динамической версии "./mod" не отображается в вызове define. В нединамическом режиме он делает.

С динамической загрузкой

define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const someCondition = true;
    if (someCondition) {
        require(["./mod"], (module) => {
            console.log(module.go());
        });
    }
});

Без динамической загрузки

define(["require", "exports", "./mod"], function (require, exports, ModuleAlias) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const someCondition = true;
    if (someCondition) {
        console.log(ModuleAlias.go());
    }
});