222

在一个 Angular 应用程序中,我看到它@Component具有 property moduleId。这是什么意思?

module.id未在任何地方定义时,该应用程序仍然有效。它怎么还能工作?

@Component({
  moduleId: module.id,
  selector: 'ng-app',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css'],
  directives: [AppComponent]
});
4

8 回答 8

185

Angular 的 beta 版本(从 vesion 2-alpha.51 开始)支持组件的相关资产,例如装饰器中的templateUrlstyleUrls 。@Component

module.id使用 CommonJS 时有效。您无需担心它是如何工作的。

请记住:在 @Component 装饰器中设置 moduleId: module.id 是这里的关键。如果您没有,那么 Angular 2 将在根级别查找您的文件。

来自Justin Schwartzenberger 的帖子,感谢@Pradeep Jain

2016 年 9 月 16 日更新:

如果您使用webpack进行捆绑,那么您不需要 module.id在装饰器中。Webpack 插件 module.id在最终包中自动处理(添加)

于 2016-05-12T06:25:08.800 回答
90

(2017-03-13) 更新

所有提及 moduleId 的内容均已删除。“组件相对路径”说明书已删除

我们在推荐的 SystemJS 配置中添加了一个新的 SystemJS 插件 (systemjs-angular-loader.js)。该插件为您动态地将 templateUrl 和 styleUrls 中的“组件相对”路径转换为“绝对路径”。

我们强烈建议您只编写与组件相关的路径。这是这些文档中讨论的唯一形式的 URL。你不再需要写@Component({ moduleId: module.id }),也不应该。

来源:https ://angular.io/docs/ts/latest/guide/change-log.html

定义:

moduleId?: string

moduleId@Component注释内的参数采用的string值是;

"包含该组件的模块的模块 ID。 "

CommonJS 用法:module.id,

SystemJS 用法:__moduleName


使用理由moduleId

moduleId如文档中所述,用于解析样式表和模板的相对路径。

包含该组件的模块的模块 ID。需要能够解析模板和样式的相对 URL。在 Dart 中,这可以自动确定,不需要设置。在 CommonJS 中,这总是可以设置为 module.id。

参考(旧):https ://angular.io/docs/js/latest/api/core/index/ComponentMetadata-class.html

我们可以通过设置 @Component 元数据的 moduleId 属性来指定模板和样式文件相对于组件类文件的位置

参考:https ://angular.io/docs/ts/latest/cookbook/component-relative-paths.html


示例用法:

文件夹结构:

RootFolder
├── index.html
├── config.js
├── app
│   ├── components
│   │   ├── my.component.ts
│   │   ├── my.component.css
│   │   ├── my.component.html


没有 module.id

@Component({
  selector: 'my-component',
  templateUrl: 'app/components/my.component.html', <- Starts from base path
  styleUrls:  ['app/components/my.component.css'] <- Starts from base path
})

使用 module.id

tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs", <- need to change this if you want to use module.id property
...


@Component({
  moduleId: module.id,
  selector: 'my-component',
  templateUrl: 'my.component.html', <- relative to the components current path
  styleUrls:  ['my.component.css'] <- relative to the components current path
})
于 2016-05-12T05:50:11.430 回答
23

如果你得到typescript error,只是declare文件中的变量。

// app.component.ts
declare var module: {
   id: string;
}
//
@Component({
   moduleId: module.id,    // now it works without annoying Typescript
   ...
})

UPDATE - December 08, 2016

module关键字在 上可用node。因此,如果您@types/node在项目中安装 ,您将module在 typescript 文件中自动使用关键字,而无需使用declare它。

npm install -D @types/node

根据您的配置,您可能必须将其包含在tsconfig.json文件中才能获取工具

//tsconfig.json
{
   ...
   "compilerOptions": {
       "types" : ["node"]
   }
   ...
}

// some-component.ts
// now, no need to declare module
@Component({
   moduleId: module.id,    // now it works without annoying Typescript
   ...
})

祝你好运

于 2016-11-05T03:15:32.427 回答
3

除了我想补充的很好的解释之外echonaxNishchit Dhanani我真的很讨厌使用module.id. 特别是,如果您支持(提前)AoT 编译,并且对于一个现实的项目,这就是您应该追求的目标,那么module.id您的组件元数据中就没有类似的地方。

文档

SystemJS使用加载器和组件相关 URL的 JiT 编译应用程序必须将@Component.moduleId属性设置为module.id. 当 AoT 编译的应用程序运行时,模块对象未定义。除非您像这样在 index.html 中分配全局模块值,否则应用程序将失败并出现空引用错误:

<script>window.module = 'aot';</script>

我认为在文件的生产版本中有这一行index.html是绝对不能接受的!

因此,目标是为开发提供(即时)JiT 编译,为生产提供 AoT 支持,并具有以下组件元数据定义:(无moduleId: module.id行)

@Component({      
  selector: 'my-component',
  templateUrl: 'my.component.html', <- relative to the components current path
  styleUrls:  ['my.component.css'] <- relative to the components current path
})

同时我想对于组件文件路径放置样式、likemy.component.css和模板文件。my.component.html my.component.ts

为了实现这一切,我使用的解决方案是在开发阶段从多个目录源托管 Web 服务器(lite-server 或 browser-sync)!

bs-config.json

{
  "port": 8000,
  "server": ["app", "."]
}

请为我详细了解此答案

依赖此方法的示例性 Angular 2 快速启动项目托管在此处

于 2016-12-15T17:40:32.840 回答
3

根据 Angular 文档,您不应使用 @Component({ moduleId: module.id })

请参考:https ://angular.io/docs/ts/latest/guide/change-log.html

以下是该页面的相关文本:

所有提及 moduleId 的内容均已删除。“组件相对路径”说明书已删除 (2017-03-13)

systemjs-angular-loader.js我们在推荐的 SystemJS 配置中添加了一个新的 SystemJS 插件 ( )。该插件为您动态地将 templateUrl 和 styleUrls 中的“组件相对”路径转换为“绝对路径”。

我们强烈建议您只编写与组件相关的路径。这是这些文档中讨论的唯一形式的 URL。你不再需要写@Component({ moduleId: module.id }),也不应该。

于 2017-04-26T06:02:16.337 回答
1

看起来如果您在 tsconfig.json 中使用“模块”:“es6”,则不必使用它:)

于 2016-10-25T14:00:15.983 回答
0

Angular 反射过程和 metadata_resolver 组件使用此 moduleId 值在构建组件之前评估完全限定的组件路径。

于 2017-08-18T04:10:24.043 回答
-2

添加moduleId: module.id修复了构建原生 Angular 应用程序和 Angular Web 应用程序时可能出现的几个问题。使用它是最佳实践。

它还使组件能够在当前目录中而不是从顶部文件夹中查找文件

于 2017-04-21T13:17:57.303 回答