2014-06-30 3 views
2

В нашей ранее существовавшей кодовой базе мы используем аспекты «Функции и функции - объекты» JavaScript для размещения имен.TypeScript: Альтернатива объединению модулей с несколькими файлами +

Например, предположим, что у нас есть класс с именем Foo, который содержит класс с именем Bar.

Foo - глобально экспортируемый объект (например, он существует в window.Foo), а window.Foo.Bar - это конструктор для Bar. (Я думаю, справедливо сказать, что это общий шаблон JavaScript).

Это правда, что этот шаблон создает направленную зависимость. Foo должен быть загружен перед баром. Мы выполняем это с помощью stealjs, асинхронного загрузчика модулей, который не соответствует протоколу AMD. По этой причине, мы не можем использовать встроенное в систему импорт/экспорт AMD. По крайней мере, пока мы не потратим несколько недель на работу, чтобы перенести всю нашу базу кода на requirejs.

Чтобы соответствовать этому образцу в машинописном, мы говорим о класса с именем Foo, и также модуль с именем Foo.

class Foo { 
    /* Foo's properties */ 
} 

module Foo { 
    export class Bar { 
    /* Bar's properties */ 
    } 
} 

Это юридическое машинопись и компилирует в ситуации JavaScript, описанной выше: объект класса Foo будет содержать объект класса Bar, как его собственность «Бар». Модуль Foo называется merge с классом Foo, а Bar считается внутренним классом . не

Однако, если я просто разделить эти два заявления в отдельные файлы:

// Foo.ts 
class Foo { 
    /* Foo's properties */ 
} 

// Foo/Bar.ts 
module Foo { 
    export class Bar { 
    /* Bar's properties */ 
    } 
} 

Это уже не юридическое машинопись, и он не компилируется. [1] (Это несмотря на то, что мы могли и могли бы загрузить второй файл после загрузки первого файла через наш собственный загрузчик модуля.)

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

Если бы мы использовали семантику импорта/экспорта, встроенную в TS, эта проблема не возникла бы, но мы не по причине, описанной выше. Портирование всего на requirejs сейчас не на столе. Учитывая нашу ситуацию, какова, по вашему мнению, лучшая стратегия для работы над ограничением слияния классов?

[1] TypeScript: Module x cannot merge with previous declaration of x in a different file

+0

Интересно, что это работает в моей среде IDE (IntelliJ), потому что он компилирует каждый файл отдельно (между модулем 'Foo' и классом' Foo' нет взаимозависимости). Не могли бы вы придумать аналогичную стратегию: независимая компиляция с использованием скрипта, затем слияние? –

+0

Вы правы, что машинопись будет «делать правильную вещь», если только она просто скомпилируется. И, мне кажется, это интересно. Но, я думаю, что, вероятно, больше работать, чтобы взломать сборку, чем взломать ограничение пространства имен. Пока мы перейдем к последнему подходу. Спасибо за предложение, однако. Я ценю это! – masonk

ответ

0

Вы можете переключиться на require.js AMD часть за один раз, а не переписать все сразу. Самый простой способ сделать это, по сути, состоит в том, чтобы полагаться на встроенную поддержку AMD в формате TypeScript, поскольку она автоматизирует так много, что вам нужно сделать, а синтаксис экспорта и импорта в TypeScript очень прост в работе. Файлы, которые вы не добавляете в них для экспорта или импорта в TypeScript, создаются так, как они есть в настоящее время, а файлы, использующие экспорт/импорт, становятся модулями AMD. Для этого есть немного кривая обучения, так как вам нужно будет добавить конфигурацию require и начать использовать шаблон require(['mytsamd'], function (mytsamd) { /* do stuff with mytsamd */ }) (или конвертировать его в обещание с чем-то вроде Q.js) в файлах, отличных от TypeScript, которые должны ссылаться на объекты AMD ,

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