Angular - What is the meanings of module.id in component?
Asked Answered
T

8

224

In an Angular app, I have seen that @Component has property moduleId. What does it mean?

And when module.id is not defined anywhere, the app still works. How can it still work?

@Component({
  moduleId: module.id,
  selector: 'ng-app',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css'],
  directives: [AppComponent]
});
Tanbark answered 12/5, 2016 at 5:43 Comment(2)
I get 404 for the linkPatriapatriarch
Updated link: blog.schwarty.com/…Bartholomeo
T
184

The beta release of Angular (since vesion 2-alpha.51) supports relative assets for components, like templateUrl and styleUrls in the @Component decorator.

module.id works when using CommonJS. You don't need to worry about how it works.

Remember: setting moduleId: module.id in the @Component decorator is the key here. If you don't have that then Angular 2 will be looking for your files at the root level.

Source from Justin Schwartzenberger's post, thanks to @Pradeep Jain

Update on 16 Sep 2016:

If you are using webpack for bundling then you don't need module.id in decorator. Webpack plugins auto handle (add it) module.id in final bundle

Tanbark answered 12/5, 2016 at 6:25 Comment(2)
How does this explain what module.id is?Forewarn
@gyozokudor If you don't have that then Angular 2 will be looking for your files at the root level.Tanbark
A
91

Update for (2017-03-13):

All mention of moduleId removed. "Component relative paths" cookbook deleted

We added a new SystemJS plugin (systemjs-angular-loader.js) to our recommended SystemJS configuration. This plugin dynamically converts "component-relative" paths in templateUrl and styleUrls to "absolute paths" for you.

We strongly encourage you to only write component-relative paths. That is the only form of URL discussed in these docs. You no longer need to write @Component({ moduleId: module.id }), nor should you.

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

Definition:

moduleId?: string

moduleId parameter inside the @Component annotation takes a string value which is;

"The module id of the module that contains the component."

CommonJS usage: module.id,

SystemJS usage: __moduleName


Reason to use moduleId:

moduleId is used to resolve relative paths for your stylesheets and templates as it says in the documentation.

The module id of the module that contains the component. Needed to be able to resolve relative urls for templates and styles. In Dart, this can be determined automatically and does not need to be set. In CommonJS, this can always be set to module.id.

ref(old): https://angular.io/docs/js/latest/api/core/index/ComponentMetadata-class.html

we can specify locations of the template and style files relative to the component class file simply by setting the moduleId property of the @Component metadata

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


Example usage:

Folder structure:

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


Without 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
})

With 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
})
Athanasia answered 12/5, 2016 at 5:50 Comment(4)
But how it works, where is the reference of module.idTanbark
@NishchitDhanani it isn't necessary but i suggest checking github.com/angular/angular/issues/6053 it maps to your map keys inside your config. Like app.Athanasia
echonax's link to the docs is currently not working -- even though it is the link on the Angular.io Component page. Try: angular.io/docs/js/latest/api/core/index/…Plasmodium
It looks like that you forgot the 'components' sub-directory of the 'app' root-directory in the approach without module.id, isn't it? I think it should be: templateUrl: 'app/components/my.component.html', styleUrls: ['app/components/my.component.css']Niddering
T
23

If you get typescript error, just declare the variable in your file.

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

UPDATE - December 08, 2016

The module keyword is available on node. So if you install @types/node, in your project, you will have module keyword automatically available in your typescript files without needing to declare it.

npm install -D @types/node

Depending on your configuration, you might have to include this in your tsconfig.json file to get the tooling:

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

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

Good Luck

Tophole answered 5/11, 2016 at 3:15 Comment(3)
tnq so much! finally i got my ng build --prod --aot working by doing npm install -D @types/node after spending a long time of fiddling :)Metropolitan
one more thing I did was moduleId: 'module.id' (notice the single quotes around module.id)Metropolitan
@AnandRockzz I am glad you found this post helpful. I don't think you need to add module.id as a string. If it worked, something seems to be incorrect. You may need to research this further.Tophole
B
4

As per Angular doc, You should not use @Component({ moduleId: module.id })

Please ref : https://angular.io/docs/ts/latest/guide/change-log.html

Here is the relevant text from that page:

All mention of moduleId removed. "Component relative paths" cookbook deleted (2017-03-13)

We added a new SystemJS plugin (systemjs-angular-loader.js) to our recommended SystemJS configuration. This plugin dynamically converts "component-relative" paths in templateUrl and styleUrls to "absolute paths" for you.

We strongly encourage you to only write component-relative paths. That is the only form of URL discussed in these docs. You no longer need to write @Component({ moduleId: module.id }), nor should you.

Brahmanism answered 26/4, 2017 at 6:2 Comment(1)
I will also add this to my answer as a disclaimer, thanks for the update.Athanasia
A
3

In addition to the great explanations from echonax and Nishchit Dhanani I want to add, that I really hate population of components with module.id. Especially, if you have support for the (Ahead-of-Time) AoT-compilation and for a realistic project this is what you should aim for, there is no place for something like module.id in your component metadata.

From the Docs:

JiT-compiled applications that use the SystemJS loader and component-relative URLs must set the @Component.moduleId property to module.id. The module object is undefined when an AoT-compiled app runs. The app fails with a null reference error unless you assign a global module value in the index.html like this:

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

I think having this line in the production version of the index.html file is absolutely not acceptable!

Therefore, the goal is to have have (Just-in-Time) JiT-compilation for development and AoT support for production with the following component metadata definition: (without moduleId: module.id line)

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

At the same time I would like to place styles, like my.component.css and template files, like my.component.html relative to the component my.component.ts file paths.

To achieve all this, the solution I am using is to host web server (lite-server or browser-sync) during development phase from multiple directory sources!

bs-config.json:

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

Please take a took at this answer for me details.

The exemplary angular 2 quick start project, which relies on this approach is hosted here.

Acquaint answered 15/12, 2016 at 17:40 Comment(0)
L
1

Looks like if your using "module": "es6" in tsconfig.json, you dont have to use this :)

Latrice answered 25/10, 2016 at 14:0 Comment(1)
will it not transpile into ES6 if we do this?Tophole
F
0

This moduleId value is used by the Angular reflection processes and the metadata_resolver component to evaluate the fully-qualified component path before the component is constructed.

Flatulent answered 18/8, 2017 at 4:10 Comment(0)
A
-2

Adding moduleId: module.id fixes several issues that can occur when building native-angular apps and angular web apps. It's best practice to use it.

It also enables the component to look in the current directory for files instead of from the top folder

Amadeo answered 21/4, 2017 at 13:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.