#javascript #node.js #typescript #tsc
#javascript #node.js #typescript #tsc
Вопрос:
Теперь я уверен, что проблема связана с тем, что включен файл d.ts, который содержит модуль с именем «Shared», и оператор require, который включает переменную с тем же именем, если она используется в среде NodeJS.
// shared.d.ts
declare module Shared { ... }
// other_module.ts
/// <reference path="shared.d.ts"/>
if(require) { var Shared = require("shared"); }
export class Something {
public someVar = new Shared.SomethingElse("blah");
}
Поэтому, когда я компилирую other_module.ts
(что на самом деле представляет собой множество отдельных файлов), он сообщает мне, что Shared — это дублированный идентификатор, который я могу понять, поскольку TS считает, что Shared — это модуль, но затем ему сообщают, что это возврат require .
Проблема здесь в том, что выходные данные модулей должны быть совместимы с системой require NodeJS, поэтому в этом случае, когда требуется other_module, он будет находиться в своей собственной области видимости и не будет знать, о Shared.SomethingElse
чем требуется require, поэтому внутренние модули в other_module
смогут получить доступ к общей библиотеке, но всреда браузера, которую он получит Shared.SomethingElse
через глобальную область.
Если я удалю ссылку, файл не будет компилироваться, поскольку он не знает об Shared
этом, если я удалю require при загрузке модуля в nodejs ( var otherModule = require("other_module")
), он будет жаловаться, что он не знает Shared
. Итак, есть ли способ решить эту проблему?
Ответ №1:
Сначала ошибка
Дубликат идентификатора, потому что у вас есть Shared
in shared.d.ts
in other_module.ts
.
ИСПРАВЬТЕ A, будьте все внешними
Если вы хотите использовать amd
/ commonjs
ie. вам нужно использовать внешние модули import/require
(не так, var/require
как вы делаете). Использование an import
создает новое пространство объявления переменных, и поэтому вы больше не загрязняете глобальное пространство Shared
other_module.ts
имен. Короче говоря :
// shared.d.ts
declare module Shared {
export function SomethingElse(arg:string):any;
}
declare module 'shared'{
export = Shared;
}
И типизированный импорт:
// other_module.ts
/// <reference path="shared.d.ts"/>
import Shared = require("shared");
export class Something {
public someVar = new Shared.SomethingElse("blah");
}
ИСПРАВЬТЕ B, как и раньше, но тогда вам нужно использовать другое имя
Внутри other_module
не используйте имя Shared
локально, если локальная область является глобальной областью. Я рекомендую вам просто использовать external везде и компилировать для узла с commonjs
и браузера с amd
, как показано в исправлении A, но если вам нужно, здесь исправлена компиляция other_module.ts
.
// other_module.ts
/// <reference path="shared.d.ts"/>
var fooShared: typeof Shared;
if(require) { fooShared = require("shared"); }
else { fooShared = Shared; }
export class Something {
public someVar = new fooShared.SomethingElse("blah");
}
Комментарии:
1. проблема в том, что мне нужно загрязнить глобальное пространство имен для использования в браузере, сценарий в основном представляет собой контракт данных на веб-сервис, который совместно используется сервером и клиентом. Поэтому я просто хочу 1 набор классов, которые можно использовать с обеих сторон. Итак, я попытался написать его таким образом, чтобы, если require etc доступен, он использовал это, в противном случае он просто полагается на то, что глобальные переменные находятся на месте. Если бы я должен был перейти по маршруту импорта, мне нужно использовать загрузчики модулей в браузере, что не так. Также для использования
import Shared
мне нужно использоватьexport module
в общей библиотеке, но это МНОГО файлов.2. Ах! ваш пример B кажется, что это сработает, попробует это и сообщит 1 для идей в любом случае.
3. Кажется, работает, так что это должно помочь мне преодолеть этот горб, по крайней мере, спасибо за помощь.