I didn't know how to state the question... So, basically I'm writing my own application using Angular 2 with Typescript. I would like to make it possible to import my modules the way we do with Angular, where we can import multiple related modules in one line. For example, we could do this in angular2 beta:
import { Component, OnInit, Input } from 'angular2/core';
I would like to do something similar with my app. For example:
import { UserService, RoleService } from 'my-project/services';
Also, I want to be able to do the same for models, pipes, components, etc...
One more thing, the folder structure would be something like this:
src/app/services
src/app/components
src/app/models
src/app/pipes
What I tried to do: On path src/app, I created on file for each 'bundle', like services.d.ts, models.d.ts, pipes.d.ts... And then I tried to map on SystemJS config, like so:
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'src/app', // 'dist',
'rxjs': 'node_modules/rxjs',
'my-project/components': 'src/app/components',
'my-project/services': 'src/app/services',
'my-project/models': 'src/app/models',
'my-project/pipes': 'src/app/pipes',
'@angular': 'node_modules/@angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { format: 'register', main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
};
var packageNames = [
'my-project/components',
'my-project/services',
'my-project/models',
'my-project/pipes',
'@angular/common',
'@angular/compiler',
'@angular/core',
'@angular/http',
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/router-deprecated',
'@angular/testing',
'@angular/upgrade',
];
// add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function(pkgName) {
packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});
var config = {
map: map,
packages: packages
};
System.config(config);
})(this);
The problem is Visual Studio Code doesn't recognize the imports in my .ts files. It says it couldn't find the module.
You need 2 things to accomplish this. First, as other answer pointed out, you need to create "barrels" (index.ts
) inside src/app/services
, src/app/models
and other such folders. So you folder structure looks something like this:
Where the index.ts
files contain the exports of stuff that you want to import in your application:
export * from './service1';
export * from './service2';
So far, this will give you the possibility to do this:
import { Service1, Service2 } from '../../services';
However, this is not ideal because of the relative paths like ../../
. In order to fix this, you need do one more step: specify baseUrl
and paths
TypeScript options in tsconfig.json
(see https://www.typescriptlang.org/docs/handbook/module-resolution.html).
If you only want to get rid of relative paths, you just need to specify the baseUrl
option like this:
tsconfig.json:
{
"compilerOptions": {
...
"baseUrl": "./src"
}
}
After this is done, you should be able to import your services like this:
import { Service1, Service2 } from 'app/services';
But if you also need to have import like my-project/services
(my-project
instead of app
), then you also need to specify paths
configuration like the following:
{
"compilerOptions": {
...
"baseUrl": "./src",
"paths": {
"my-project/*": [
"app/*"
]
}
}
}
With this configuration the following should work:
import { Service1, Service2 } from 'my-project/services';
You'll want to create a barrel inside the services
folder (for example) which will export all nested exports manually, this way you can import 2 (or more) modules from the barrel, where before you'd have to use 2 different imports.
Last I heard, this breaks tree-shaking for some reason, but I might wrong about this.
Anyway, read up some more here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With