angular - 是否可以使用 typescript 命名空间来组织 angular 模块和组件文件?

例如下面的代码没有按预期工作。假设我有按钮命名空间:

namespace Button {

  @Component({
    selector: 'super-button',
    templateUrl: './button.component.html',
    styleUrls: ['./button.component.scss']
  })
  export class ButtonComponent {}

  @NgModule({
    declarations: [
      ButtonComponent
    ],
    imports: [
      CommonModule
    ],
    exports: [ButtonComponent]
  })
  export class ButtonModule { }

}
 
export default Button;

在 app.module 中:

import Button from './button';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,

    Button.ButtonModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

我收到此编译错误:

<e> [webpack-dev-middleware] Error: [object Object]
<e>     at analyzingFileEmitter (E:\Projects\Angular\test-app\node_modules\@ngtools\webpack\src\ivy\plugin.js:452:23)
<e>     at processTicksAndRejections (node:internal/process/task_queues:96:5)
<e>     at async AngularWebpackPlugin.rebuildRequiredFiles (E:\Projects\Angular\test-app\node_modules\@ngtools\webpack\src\ivy\plugin.js:277:36)
<e>     at async E:\Projects\Angular\test-app\node_modules\@ngtools\webpack\src\ivy\plugin.js:218:17

更重要的是,如何将组件和模块拆分为不同的文件,同时仍将它们放在同一个命名空间中?我尝试了以下方法,但无济于事:https://www.typescriptlang.org/docs/handbook/namespaces.html#multi-file-namespaces

我的观点是用大量的组件和模块来组织项目。我有很多名称很长的文件来描述其功能,例如:

-> very-descriptive-A-list.module
-> very-descriptive-A-list.component
-> very-descriptive-A-list-item.component
-> very-descriptive-A-list-modal.component etc

我只想创建一个包含每个功能的命名空间,就像这样:

-> very-describtive-A namespace:
->> list.module,
->> list.component,
->> item.component
->> modal.component etc

-> very-describtive-B namespace:
->> list.module,
->> list.component,
->> item.component
->> modal.component etc

对于其他所有功能,依此类推。我只是在考虑减少文件名中的样板文件,这对 IDE 智能感知也有好处,因为命名空间内的组件被封装和隐藏。

回答1

Typescript 命名空间在这一点上基本上已经过时了。 TypeScript 在 ES 模块被添加到 ES6 之前就有这个概念。 TypeScript 的设计目标是尽可能使语言与 ECMA 保持同步,因此虽然它可能在 ECMA 之前有一个特性,但如果以后添加它,它将有利于本机实现。 TypeScript 的“外部模块”现在在很大程度上与 ES 模块没有区别,并且对于这两个用例来说都足够了。请参阅 https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html#needless-namespacing

您正在寻找的行为是 index.ts 文件的目的。通常,当给定目录有一个 index.ts 时,这意味着该目录的其他内容是“内部的”(即不被目录之外的任何东西使用),而从索引导出的东西是“外部模块” .

button
├── button-component.ts
├── button-module.ts
└── index.ts

index.ts 通常看起来像:

export { ButtonComponent } from './button-component';
export { ButtonModule } from './button-module';

对于您问题中的行为,您可以将整个模块导入到一个变量中,例如:

import * as Button from './button';

// ...
imports: [
  Button.ButtonModule,

但是,更常见的是只导入所需的特定成员,例如:

import { ButtonModule } from './button';

你当然可以用任何一种方式来做,但前者更符合习惯,正如在同一个地方使用的 CommonModuleAppRoutingModule 所证明的那样。显式命名空间是不必要的,因为 import 的源代码没有歧义。

import * as 语法在一些导出大量你一起使用的东西的情况下很方便,但典型的用例是导出一组密切相关的函数的模块,而不是一堆类型。例如。

api/
├── create-user.ts
├── delete-user.ts
├── get-user.ts
├── index.ts
└── update-user.ts
import * as api from './api';

// ...
await api.getUser(123);
await api.deleteUser(123);

它与导出具有所有这些方法的对象的 api.ts 没有区别,但在单独的文件中组织代码很方便。

相似文章

最新文章