如何将多个TypeScript模块打包成组以进行组织

时间:2016-01-27 15:51:34

标签: angularjs typescript

我的TypeScript项目已经发展到适中的规模,我正试图想出一个很好的方法来组织它。

目前,该项目(Angular 1.x应用程序)具有以下结构:

-app/
 |
 |-components/
 | |
 | |-component A/
 | | |
 | | |-(..models..).ts
 | | |-(..services..).ts
 | |
 | |-component B/
 | | |
 | | |-(..models..).ts
 | | |-(..directives..).ts
 | |
 | (...)
 | |
 | |-component Z/
 | | |
 | | |-(..directives..).ts
 | | |-(..services..).ts
 | |
 | |-components.ts
 |
 |-app.ts

基本上,我已经逻辑地对应用程序组件进行了分组,因此例如Video组件将在单个目录中声明其模型和服务。然后我将所有组件导入到单个文件app/components.ts并重新导出它们。

 // models
 export * from './componentA/models.ts';
 export * from './componentB/models.ts';
 export * from './componentC/models.ts';

 // services
 export * from './componentA/services.ts';
 export * from './componentX/services.ts';
 export * from './componentZ/services.ts';

 // directives
 export * from './componentB/directives.ts';
 export * from './componentY/directives.ts';
 export * from './componentZ/directives.ts';

然后我也会在每个组件中导入app/components.ts文件,因为我几乎总是每次都需要多个组件,而且每个组件单独导入都会非常重复。

 // app/components/componentA/services.ts
 import * as ProjectName from '../components.ts';

 export class ComponentA_Service1 extends ProjectName.BaseService {

     protected $http: ng.IHttpService;
     protected $log: ng.ILogService;
     protected configService: ProjectName.ConfigService;

     /** @ngInject */
     constructor($http: ng.IHttpService, $log: ng.ILogService, ConfigService: ProjectName.ConfigService) {

         this.$http = $http;
         this.$log = $lot;
         this.configService = ConfigService;
     }

     // (.....)
 }

 export class ComponentA_Service2 { /* ... */ }
 export class ComponentA_Service3 extends ProjectName.ComponentZ_Service4 { /* ... */ }

这项工作有一段时间了,但现在该项目已经定义了几十个类和接口。 ProjectName与几十名成员混在一起。

我想要的是根据不同的成员将它们组合在一起。例如,结构如:

 namespace ProjectName {

     namespace Models {

         class ComponentA_Model1 { /* ... */ }
         class ComponentA_Model2 { /* ... */ }
         class ComponentB_Model1 { /* ... */ }
     }

     namespace Services {

         class ComponentA_Service1 { /* ... */ }
         class ComponentA_Service2 { /* ... */ }
         class ComponentZ_Service4 { /* ... */ }
     }

     namespace Directives {

         class ComponentB_Directive1 { /* ... */ }
         class ComponentY_Directive2 { /* ... */ }
         class ComponentZ_Directive3 { /* ... */ }
     }
 }

到目前为止,我无法弄清楚如何使用TypeScript实现这一目标。更具体地说,我无法import几个不同的模块,export它们只是一个模块。

任何想法,如果它甚至可能在TypeScript中,或者我在这里走向一个完全错误的方向?

更新(2016年1月31日):我认为我应该添加我最终做的事情。我已经开始尝试类似于下面@Vadim Macagon建议的架构。虽然这是我正在做的事情的正确解决方案,但我最终决定反对它,因为@mk.在下面接受的答案中指出了原因。

我现在直接在每个文件中从各自的目录导入单个模块。虽然在编写代码时肯定会有轻微的开销,但它仍然是更好的方法。

2 个答案:

答案 0 :(得分:5)

你已经熟悉了重新导出,所以我相信这样的事情应该有效:

// models.ts
export * from './componentA/models.ts';
export * from './componentB/models.ts';
export * from './componentC/models.ts';

// services.ts
export * from './componentA/services.ts';
export * from './componentX/services.ts';
export * from './componentZ/services.ts';

// directives.ts
export * from './componentB/directives.ts';
export * from './componentY/directives.ts';
export * from './componentZ/directives.ts';

// projectname.ts
import * as Models from './models';
import * as Services from './services';
import * as Directives from './directives';

export { Models, Services, Directives };

// app.ts
import { Models, Services, Directives } from './projectname';
// OR
import * as ProjectName from './projectname';

答案 1 :(得分:2)

以下是一些建议:

  1. 不要混合内部(命名空间)和外部模块,为整个项目选择一个并坚持下去。使用外部模块。除了声明合并之外,不要使用名称空间/内部。请参阅this article和其他人。
  2. 不要重新导出:它可以使导航到原始文件更加繁琐,并打破一些工具(如查找用法)。它还创建了对同一资源的两个引用 - 原始资源和重新导出资源。如果你的代码库在其中一个文件中调用副作用,这可能会掩盖副作用。
  3. 您似乎正在尝试最小化您的导入,但结果是您从一个全局"导入注册表"导入项目中的所有内容。文件。对于某些组合良好的t.ds文件,庞大的定义可能没问题,但对于导入则不行。相反,将模块视为文件,并根据需要单独导入它们:

    import { MyClass } from "../foo/bar/MyClass";
    import { toString, otherUtil } from "../foo/baz/Utils";
    

    换句话说,不使用导入注册表文件,而是使用目录结构对文件/模块进行分组。这样做的一个小但很好的结果是你可以写extends BaseService而不是总是符合资格,如extends ProjectName.BaseService。如果您有太多导入(或导出太多),这表明该文件可能需要拆分。