I followed A_Singh's idea, but had to adapt it a little since my systemjs.config.js
is different, based on the tour-of-heroes tutorial as of right now. (June 3, 2016 - RC1).
This modification works, and under VisualStudio Code, Intellisense
worked well for me.
I have also, been playing with directory structure to keep things modular, and here is where the barrels made sense.
This is how I have modified the tour-of-heroes
project
app
|- main.ts
|- app.component.ts
|- app.component.css
|-+ components
| |-+ dashboard
| |- dashboard.component.css
| |- dashboard.component.html
| |- dashboard.component.ts
|-+ modules
| |-+ hero
| |- index.ts <-- //The barrel for the Hero module
| |-+ components
| | |-+ detail
| | | |- hero-detail.component.css
| | | |- hero-detail.component.html
| | | |- hero-detail.component.ts
| | |-+ list
| | |- hero-list.component.css
| | |- hero-list.component.html
| | |- hero-list.component.ts
| |-+ models
| | |- hero.model.ts
| |-+ services
| |- hero.service.ts
| |- mock-heroes.ts
And here the updated systemjs.config.js
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'app', // 'dist',
'@angular': 'node_modules/@angular',
'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
'rxjs': 'node_modules/rxjs',
// The added barrel map
'hero': 'app/modules/hero'
};
var packages = {
'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' },
// The package definition (notice I had to declare index.js)
'hero': { main: 'index.js', defaultExtension: 'js' }
};
var ngPackageNames = [
'common',
'compiler',
'core',
'http',
'platform-browser',
'platform-browser-dynamic',
'router',
'router-deprecated',
'upgrade',
];
ngPackageNames.forEach(function(pkgName) {
packages['@angular/'+pkgName] = { main: pkgName + '.umd.js', defaultExtension: 'js' };
});
var config = {
map: map,
packages: packages
}
System.config(config);
})(this);
And finally, here is how the app.component.ts
now looks like
import { Component } from '@angular/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { HeroListComponent, HeroDetailComponent, HeroService } from './modules/hero';
@Component({
selector: 'my-app',
directives: [ROUTER_DIRECTIVES],
providers: [
ROUTER_PROVIDERS,
HeroService
],
template: `
<h1>{{title}}</h1>
<nav>
<a [routerLink]="['Dashboard']">Dashboard</a>
<a [routerLink]="['HeroList']">Hero List</a>
</nav>
<router-outlet></router-outlet>
`,
styleUrls: ['app/app.component.css']
})
@RouteConfig([
{
path: '/dashboard',
name: 'Dashboard',
component: DashboardComponent,
useAsDefault: true
},
{
path: '/hero-list',
name: 'HeroList',
component: HeroListComponent
},
{
path: '/detail/:id',
name: 'HeroDetail',
component: HeroDetailComponent
}
])
export class AppComponent {
title: string = 'Tour of Heroes';
}
One final note, you could do the import as
import { HeroListComponent, HeroDetailComponent, HeroService } from 'hero';
And it will work, however, since it is not technically a NodeJS imported module, VS Code complains that it cannot find it.
So, my personal choice is to leave the explicit ./modules/hero
, it helps me know that it is one of my modules and not an imported one and I'm happy to not see red lines.