是否可以使用打字稿命名空间来组织 angular 模块和组件文件?
Is it possible to organize angular modules and component files with typscript namespaces?
例如,下面的代码没有按预期工作。假设我有按钮命名空间:
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 智能感知也有好处,因为命名空间内的组件被封装和隐藏了。
Typescript 命名空间在这一点上基本上已经过时了。在 ES 模块加入 ES6 之前,TypeScript 就有这个概念。 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';
你当然可以做这两种方式,但前者更惯用,正如在同一个地方使用的CommonModule
或AppRoutingModule
所证明的那样.显式命名空间完全没有必要,因为 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
没有区别,但是将代码组织在单独的文件中很方便。
例如,下面的代码没有按预期工作。假设我有按钮命名空间:
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 智能感知也有好处,因为命名空间内的组件被封装和隐藏了。
Typescript 命名空间在这一点上基本上已经过时了。在 ES 模块加入 ES6 之前,TypeScript 就有这个概念。 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';
你当然可以做这两种方式,但前者更惯用,正如在同一个地方使用的CommonModule
或AppRoutingModule
所证明的那样.显式命名空间完全没有必要,因为 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
没有区别,但是将代码组织在单独的文件中很方便。