Typescript,CommonJS&的循环依赖问题浏览器 [英] Circular dependency issue with Typescript, CommonJS & Browserify

查看:157
本文介绍了Typescript,CommonJS&的循环依赖问题浏览器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将一个相当大的打字稿项目从内部模块转移到外部模块。之所以这样做,是因为我想创建一个核心捆绑包,如果需要,可以加载其他捆绑包。我要记住的第二个要求是,我也希望能够在具有nodeJS的服务器上运行捆绑软件(如果需要,还可以进行一些修改)。

I'm in the process of moving a fairly large typescript project from internal modules to external modules. I do this because I want to create one core bundle, which, if and when required, can load other bundles. A seccond requirement which I'm keeping in mind is that I'd like to be able to run the bundles (with some modifications if required) on the server with nodeJS aswell.

我首先尝试使用AMD& require.js来构建核心捆绑包,但是我遇到了一个循环依赖的问题。在阅读了require.js的常见知识之后,对于大型项目更常建议使用commonJS,我尝试了一下。但是,现在它与browserify一起设置了,当我运行已编译的包时,在完全相同的位置出现了 exact 相同的问题。

I first tried using AMD & require.js to build the core bundle, but I came across an issue with circular dependencies. After having reading that this is common with require.js and commonJS is more often adviced for large project I tried that. But now that it's set up together with browserify I have the exact same issue coming up at the exact same place when I run the compiled bundle.

我有大约10个基本类,它们彼此高度依赖并形成多个循环依赖项。我看不到任何删除它们的方法。

I have something like 10 base classes that havily rely on eachother and form multiple circular dependencies. I don't see any way to remove all of them.

一个简化的设置来解释为什么我认为我不能删除循环依赖项:

A simplified setup to explain why I don't think I can remove the circular dependencies:

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

我已经在此处阅读了多个相关问题(最有帮助),并通过t我只能收集几个选项:

I've read multiple related issues here on SO (this one being most helpful), and from what I can gather I only have a few options:

1)将所有具有循环依赖关系的基类放入1个文件中。

这意味着它将成为文件的地狱。导入将始终需要别名:

This means it will become one hell of a file. And imports will always need aliases:

import core = require('core');
import BaseA = core.BaseA;

2)使用内部模块

当我使用内部打字稿模块和参考文件时,核心捆绑包运行良好(具有循环依赖性)。但是,如果我想创建单独的包并在运行时加载它们,则必须对所有带有require.js的模块使用垫片。

The core bundle worked fine (with its circular dependencies) when I used internal typescript modules and reference files. However if I want to create separate bundles and load them at run time, I'm going to have to use shims for all modules with require.js.

尽管我不太喜欢所有别名,但我想我现在将尝试选项1,因为如果可行我可以继续使用CommonJS和browserify,以后再可以更轻松地在node的服务器上运行所有内容。如果1无法解决问题,我将不得不求助于选项2。

Though I don't really like all the aliasing, I think I will try option 1 now, because if it works I can keep going with CommonJS and browserify and later on I can also more easily run everything on the server in node. And I'll have to resort to option 2 if 1 doesn't work out.

Q1:是否有我未提及的某些解决方案?

Q1: Is there some possible solution I havn't mentioned?

第二季度:什么是具有1个核心包的打字稿项目的最佳设置,该项目可以按需加载其他包(在核心上构建)。似乎不能绕过循环依赖。最好在客户端和服务器上都可以运行。

Q2: what is the best setup for a typescript project with 1 core bundle which loads other bundles (which build upon the core) on demand. Which seems to cannot go around circular dependencies. And which preferably can run both on the client and the server.

还是我只是在问不可能的事? :)

Or am I just asking for the impossible? :)

推荐答案

如果您有 ModuleA 和 ModuleB 彼此依赖,它们不是模块。它们在单独的文件中,但它们的行为不像 modules

Simply put (perhaps simplistically, but I don't think so), if you have ModuleA and ModuleB and both rely on each other, they aren't modules. They are in separate files, but they are not acting like modules.

在您的情况下,类是高度相互依赖的,您不能使用这些类中的任何一个而不必全部使用它们,因此,除非您可以重构程序以单向而不是双向(例如)尝试建立依赖关系,否则我会将类组视为单个模块。

In your situation, the classes are highly interdependent, you can't use any one of those classes without needing them all, so unless you can refactor the program to try an make the dependencies one-way, rather than two-way (for example), I would treat the group of classes as a single module.

如果确实将所有这些都放在一个模块中,则仍然可以通过移动某些依赖项将其分解为模块(例如,所有这些问题在很大程度上都是夸张的(您需要问自己一个问题), Triple Resource 会共享什么?可以将其转移到他们都可以依靠的课程中吗?为什么 Triple 需要了解有关 TripleCollection 的信息(可能因为这代表了一些分层数据)?可能只有一些事情可以移动,但是从当前设计中删除的任何依赖关系都将降低复杂性。例如,如果可以删除 Triple 资源之间的双向关系。

If you do put all of these in a single module, you may still be able to break it into modules by moving some of the dependencies, for example (and all of these questions are largely rhetorical as they are the kind of question you would need to ask yourself), what do Triple and Resource share on each other? Can that be moved into a class that they could both depend on? Why does a Triple need to know about a TripleCollection (probably because this represents some hierarchical data)? There may only be some things you can move, but any dependency removed from this current design will reduce complexity. For example, if the two-way relationship between Triple and Resource could be removed.

可能您现在无法实质性地更改此设计,在这种情况下,您可以将其全部放入一个模块中,这将在很大程度上解决模块加载问题,并且还将代码保持在一起

It may be that you can't substantially change this design right now, in which case you can put it all in one module and that will largely solve the module loading issue and it will also keep code together that is likely to change for the same reason.

所有这些的摘要是:


如果具有双向模块依赖关系,请将其设为单向模块依赖关系。通过将代码移动到一种方式来实现依赖关系,或者将其全部移动到一个更老实地表示模块之间耦合的更大模块中,即可做到这一点。

If you have a two way module dependency, make it a one-way module dependency. Do this by moving code to make the dependency one way or by moving it all into a single larger module that more honestly represents the coupling between the modules.

所以我对您的选择的看法与您的问题稍有不同...

So my view on your options is slightly different to those in your questions...

1)尝试重构代码以减少耦合以查看如果您可以保留较小的模块

失败...

2)将所有具有循环依赖关系的基类放在1个文件中。

我不会将内部模块选项放在列表中-我认为外部模块是管理大型程序的更好方法。

I wouldn't place the internal modules option on the list - I think external modules are a much better way of managing a large program.

这篇关于Typescript,CommonJS&的循环依赖问题浏览器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆