2016-09-28 2 views
2

У меня возникли проблемы с тем, что WebPack вводит импортированные зависимости для проекта, написанного на языке TypeScript. Моя первая проблема заключается в получении TypeScript для распознавания импортированного модуля.Импорт и настройка модуля TypeScript

У меня есть header.ts файл, объявляющий модуль, который вложен под vi.input и экспортирует класс VIInputDirective. В файле main.ts, я пытаюсь импортировать экспортированный класс VIInputDirective из файла header.ts, но, похоже, не может получить TypeScript для его распознавания.

header.ts

module vi.input.header { 
    import IDirective = angular.IDirective; 

    export class VIInputDirective implements IDirective { 
    ... 
    } 
} 

main.ts

import {VIInputDirective} from "./header.ts"; // Nothing imported; Cannot Resolve issue 
VIInputDirective.whatever(); // Does not work 

material.dt.s

declare module vi.input { 
    ... 
} 

Если я SWAP import {VIInputDirective} from "./header.ts"; в main.ts файл с import VIMHeaderDirective = vi.input.header.VIInputDirective; он работает отлично, но потом WebPack на transpile/инъекционные дает мне следующую ошибку:

VM1469:1Uncaught ReferenceError: vi is not defined 

Я пытался экспортировать vi.input.header модуль непосредственно (т.е. экспорт модуля vi.input.header), но это не сработало. Я также попытался использовать ссылку sytnax для включения файла, но это тоже не сработало: ///<reference path="file_path"/>.

Это проблема с вложением модулей, потому что, если я удалю модуль и напрямую экспортирую класс VIInputDirective, он отлично работает. Однако я хочу сохранить его во вложенном модуле.

+0

Вы пытались импортировать * как x из "./header", тогда новый x.vi.input.header.VIInputDirective – Banners

+0

Также, возможно, вам стоит попробовать добавить инструкцию экспорта в объявление модуля (теперь оно изменено на «пространство имен» в typescript) – Banners

+0

Просто попробовал это «импортировать» как VIInputDirective из «./header.ts», а TypeScript не может найти модуль. Я получаю сообщение «Не удается разрешить файл». Если я не завершу header.ts в модуле (т.е. модуль vi.input.header {}), он отлично работает, но я хочу сохранить это. – sags

ответ

2

Вы не используете модули. Модули имеют один или несколько верхних разрядов import или export. Вместо этого вы используете глобальное пространство имен и создаете пространства имен подменю глобального пространства имен для организации вашей программы. Это называется шаблоном раскрывающего модуля. Это не связано с использованием модулей.

К сожалению, TypeScript используется для обозначения этого шаблона с использованием Внутренние модули. Эта терминология с тех пор устарела, и использование синтаксиса module x {} (обратите внимание на отсутствие " с около x) настоятельно не рекомендуется. Язык вводит синонимическое ключевое слово namespace, чтобы уменьшить путаницу.

JavaScript-загрузчики и коммутаторы, такие как Webpack, RequireJS и SystemJS, работают с модулями, то есть TypeScript, называемый внешними модулями ..

Для уточнения следующих конструкций вы упоминание не модуля связанного

  1. верхнего уровень неэкспортированной module/namespace синтаксических декларации

    module vi.input.header { ... } 
    

    это теперь будет написано как

    namespace vi.input.header { ... } 
    

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

    var vi; 
    (function (vi) { 
        var input; 
        (function (input) { 
         var header; 
         (function (header) { 
         })(header = input.header || (input.header = {})); 
        })(input = vi.input || (vi.input = {})); 
    })(vi || (vi = {})); 
    

    Примечание Этот мутирует глобальный масштаб в шаблоне обычно используется различными библиотеками. namespace s (ранее называемые внутренними модулями), как и выше, обладают интересным свойством, что несколько файлов могут способствовать их содержимому, и это на самом деле их основная цель. Это объясняет степень вложенности и условных присвоений переменным в испускаемом выше значении. Это не имеет никакого отношения к использованию Модули.

  2. import задание, которые ссылаются на namespace элементов, такие как

    import IDirective = angular.IDirective; 
    

    не квалифицируется как верхний уровень import деклараций, и, следовательно, не вызывает их, содержащий файл, который будет рассматриваться как модуль. Это верно, даже если они размещены на верхнем уровне файла. Причина в том, что модульные системы, будь то AMD, CommonJS, System или ES2015, все используют строки как спецификаторы модулей, импортируя из таких строк; которые, кстати, могут представлять пути к файлам, URL-адреса, разрешенные простые имена или идентификаторы синтетического модуля.

Опять же, import name = qualified.global.name заявления в вашем коде машинопись особенность, которая не имеет никакого отношения к модулей. Они могут быть весьма полезны для сглаживания вложенных типов и значений, но модулей они не делают.

Теперь здесь становится интересно, и где она пересекается с конкретным вопросом namespace ы может быть использован, и порой весьма изящно, с ввнешних модулей, но их семантика очень разные

Рассмотрение

услуги.ц

export namespace app { 
    export class SomeService { } 
} 

, который компилируется в следующих JavaScript

export var app; 
(function (app) { 
    class SomeService { 
    } 
    app.SomeService = SomeService; 
})(app || (app = {})); 

main.ts

export namespace app { 
    export function bootstrap() { } 
} 

который компилирует в следующий JavaScript

export var app; 
(function (app) { 
    function bootstrap() { } 
    app.bootstrap = bootstrap; 
})(app || (app = {})); 

Оба выше внешние модули, то есть истинные модули, что использование пространства имена как внутренние механизмы организации коды, но они ключ вынос в том, что они не внести свой вклад в поделилсяapp имен, каждый из которых имеет свои собственное, файл область видимости app переменная. Ни один из них не имеет неявного доступа к другим членам, объявления namespace app не объединяются между файлами, а их аналогичная внутренняя схема именования связана с их модулярностью.

Итак, как все это относится к вашему вопросу и к предложениям, которые вы пытались применить?

Давайте посмотрим

headers.ts

module vi.input.header { 
    import IDirective = angular.IDirective; 

    export class VIInputDirective implements IDirective { 
    static whatever() { } 
    } 
} 

Этот файл не является модулем, так как объяснить выше, и использует глобальное пространство имен, чтобы выставить свои заявления. Если бы мы писали это сегодня, мы использовали бы ключевое слово namespace вместо ключевого слова module по соглашению.

main.ts

import {VIInputDirective} from "./header.ts"; // Nothing imported; Cannot Resolve issue 
VIInputDirective.whatever(); // Does not work 

Действительно ни линия работает, потому что вы импортируете headers.ts, как если бы это был модуль, но, как мы только что видели, это не модуль. Кроме того, первая строка, которая является оператором верхнего уровня import, который импортирует из строки спецификатора модуля, по иронии судьбы составляет main.ts, сам по себе модуль.

Короче говоря, два стиля не очень хорошо сочетаются, и обмен кодами между ними не прост и не является чем-то, что вы, вероятно, попытаетесь сделать (я оставил формат UMD из этого ответа, чтобы попытаться сохранить его относительно простым).

Теперь мы прошли полный круг

сильный текст

declare module vi.input { 
    .... 
} 

If I swap import {VIInputDirective} from "./header.ts"; in the main.ts file with import VIMHeaderDirective = vi.input.header.VIInputDirective; it works fine, but then webpack on transpile/inject gives me the following error:

Действительно, как описано выше. Этот import, который не нацелен на строку спецификатора модуля и отсутствие каких-либо других импортов или экспорта верхнего уровня, изменяет main.ts так, что он больше не является модулем.Это приводит к тому, что TypeScript корректно проверяет правильность TypeCheck, глобальные переменные, ссылающиеся друг на друга с использованием import = namespace.value, совершенно законны, но это не модули, а инструменты JavaScript, такие как Webpack, работают с модулями.

Итак, как бы вы могли написать это приложение в этом смелом новом мире? Поскольку вы используете инструмент для связывания модулей, Webpack, вы должны писать его, используя надлежащие модули до конца.

main.ts

import {VIInputDirective} from "./header.ts"; 
VIInputDirective.whatever(); 

headers.ts

import {IDirective} from 'angular'; 

export class VIInputDirective implements IDirective { 
    static whatever() { } 
} 

material.d.ts больше не выглядит, как это было, когда вы писали это, как это было обновляется для работы с соответствующими модулями. Если вам нужно ссылаться на что-то из него, используйте синтаксис модуля

моего-диалоговый-options.ts

import {material} from 'angular'; 

const dialogOptions: material.IDialogOptions = { ... }; 

export default dialogOptions; 

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

0

Вы ищете пространства имен, а не модуль, так что.

header.ts

export namespace vi.input.header { 
    export class VIInputDirective { 

    } 
} 

main.ts

import { vi } from "./header.ts"; 
var foo = new vi.input.header.VIInputDirective(); 
+0

После обновление заголовка. ts в _export namespace_ и используя синтаксис импорта, TS-компилятор выдает ошибку «Can not find name header». Возможно, это связано с моим файлом ** material.dt.s **, где я объявляю модуль _declare vi.input {} _? – sags

+0

Я пробовал все, и ничего не работает, кроме удаления пространства имен. – sags

Смежные вопросы