Проблема круговой зависимости с Typescript, CommonJS и Browserify
Я в процессе перемещения довольно большого проекта typescript из внутренних модулей во внешние модули. Я делаю это, потому что хочу создать один основной пакет, который при необходимости может загружать другие пакеты. Требование seccond, которое я имею в виду, заключается в том, что я хотел бы иметь возможность запускать пакеты (с некоторыми изменениями, если требуется) на сервере с nodeJS.
Я сначала попытался использовать AMD & require.js для создания основного пакета, но я столкнулся с проблемой с круговыми зависимостями. После прочтения, что это общее с require.js и commonJS чаще рекомендуются для большого проекта, который я пробовал. Но теперь, когда он вместе с browserify у меня точно та же проблема возникает в том же месте, когда я запускаю скомпилированный пакет.
у меня есть что-то вроде 10 базовых классов, которые havily полагаются друг на друга и образуют несколько круговых зависимостей. Я не вижу способа удалить их все.
упрощенная настройка, чтобы объяснить, почему я не думаю, что могу удалить циклические зависимости:
Triples are made of 3 Resources (subject,predicate,object)
Resource has TripleCollections to keep track of which triples its used in
Resource has multiple functions which rely on properties of Triple
Triple has some functions which handle TripleCollections
TripleCollection has multiple functions which uses functions of Triple
TripleCollection.getSubjects() returns a ResourceCollection
ResourceCollection.getTriples() returns a TripleCollection
Resource keeps track of the objects of its triples in ResourceCollections
ResourceCollection uses multiple functions of Resource
Я прочитал несколько связанных вопросов здесь на SO (этот быть самым полезным), и из того, что я могу собрать, у меня есть только несколько вариантов:
1) Поместите все базовые классы с круговыми зависимостями в 1 файл.
это означает, что он станет одним из ада файла. А импорт всегда будет нужен псевдонимы:
import core = require('core');
import BaseA = core.BaseA;
2) Используйте внутренние модули
основной пакет работал нормально (с его круговыми зависимостями), когда я использовал внутренние модули typescript и справочные файлы. Однако если я хочу создать отдельные пакеты и загружать их во время выполнения, мне придется использовать прокладки для всех модулей с требуют.js.
хотя мне не очень нравится все сглаживание, я думаю, что попробую Вариант 1 сейчас, потому что, если он работает, я могу продолжать с CommonJS и browserify и позже я также могу более легко запускать все на сервере в узле. И мне придется прибегнуть к варианту 2, если 1 не сработает.
Q1: есть ли какое-то возможное решение, о котором я не упоминал?
Q2: какая лучшая настройка для проекта typescript с 1 основным пакетом, который загружает другие пакеты (которые строятся на ядре) по требованию. Который, похоже, не может обойти круговые зависимости. И который предпочтительно может работать как на клиенте, так и на сервер.
или я прошу невозможного? :)
1 ответов
проще говоря (возможно, упрощенно, но я так не думаю), если у вас есть ModuleA
и ModuleB
и оба полагаются друг на друга, они не являются модулями. Они находятся в отдельных файлах, но они не действуют как модули.
в вашей ситуации классы сильно взаимозависимы, вы не можете использовать ни один из этих классов без необходимости их всех, поэтому, если вы не можете рефакторировать программу, чтобы попытаться сделать зависимости односторонними, а не двусторонними (например), я рассматривал бы группу классов как единый модуль.
если вы поместите все это в один модуль, вы все равно сможете разбить его на модули, переместив некоторые из зависимостей, например (и все эти вопросы в основном риторические, поскольку они являются вопросом, который вам нужно будет задать себе), что делать Triple
и Resource
поделиться друг с другом? Может ли это быть перенесено в класс, от которого они оба могут зависеть? Почему a Triple
нужно знать о TripleCollection
(вероятно, потому, что это представляет некоторые иерархические данные)? Могут быть только некоторые вещи, которые вы можете переместить, но любая зависимость, удаленная из этого текущего дизайна, уменьшит сложность. Например, если двусторонняя связь между Triple
и Resource
может быть удален.
возможно, вы не можете существенно изменить этот дизайн прямо сейчас, и в этом случае вы можете поместить все это в один модуль, и это в значительной степени решит проблему загрузки модуля, и это также держите код Вместе, который, вероятно, изменится по той же причине.
резюме всего этого:
если у вас есть двусторонняя зависимость модуля, сделайте ее односторонней зависимостью модуля. Сделайте это, переместив код, чтобы сделать зависимость в одну сторону или переместив все это в один больший модуль, который более честно представляет связь между модулями.
таким образом, мой взгляд на ваши варианты немного отличается от ваших вопросы...
1) Попробуйте рефакторинг кода, чтобы уменьшить сцепление, чтобы увидеть, можете ли вы сохранить меньшие модули
в случае неудачи...
2) Поместите все базовые классы с круговыми зависимостями в 1 файл.
Я бы не помещал опцию внутренних модулей в список - я думаю, что внешние модули-гораздо лучший способ управления большой программой.