i'm using Angular2 and SystemJS to create a web application. I have some modules in my app and in the router configuration i use lazy loading to open them.
Here is a routing file of my app that lazy loads two modules:
const appRoutes: Routes = [
{ path: '', component: MainComponent,
canActivate: [AuthGuard],
children: [
{ path: 'dashboard', component: DashboardComponent },
{ path: 'first-section', loadChildren: 'app/modules/FIRST-SECTION/first-section.module' },
{ path: 'second-section', loadChildren: 'app/modules/SECOND-SECTION/second-section.module' },
{ path: 'documents', component: DocumentsComponent },
{ path: 'users', component: UsersComponent },
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' }
]
}
];
I use Gulp for creating tasks for development server and for production build. For the build i use SystemJS Builder that create the minified JS file for the whole app.
gulp.task('app-bundle', function() {
var builder = new Builder('src', 'src/systemjs.config.js');
return builder.buildStatic('app/main.js', 'build/scripts/app.min.js', { minify: true });
});
But... if i try to run a server on the build package the app doesn't work when it tried to run the lazy loaded modules. It gives me the following error:
GET http://127.0.0.1:8080/app/modules/FIRST-SECTION/first-section.module 404 (Not Found)
Here is my systemjs.config.js
file:
(function (global) {
System.config({
paths: {
'npm:': './node_modules/',
},
map: {
app: 'app',
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
'rxjs': 'npm:rxjs',
'lodash': 'npm:lodash/lodash.min.js',
'jquery': 'npm:jquery/dist/jquery.min.js',
},
packages: {
app: { main: './main.js', defaultExtension: 'js' },
rxjs: { defaultExtension: 'js' },
}
});
})(this);
EDIT:
As described on SystemJs Builder site with static bundles we don't need SystemJs to load modules. In fact I'm creating a static bundle (with buildStatic
, instead of bundle
), but since I'm excluding SystemJs it seems there aren't other ways to lazy load modules.
So how to create a production build using bundle
and then using lazy loading modules but without SystemJS (without systemjs.config.js
file in the dist
folder)? I see WebPack can do it...
See if you can appease system.js by providing a map for the required module. So when system.js finds the path modules/FIRST-SECTION/first-section.module , you tell it : Hey , could you map this path to modules/FIRST-SECTION/first-section.module.js without screaming in the console. Hope this helps .
(function (global) {
System.config({
paths: {
'npm:': './node_modules/',
},
map: {
app: 'app',
'modules/FIRST-SECTION/first-section.module':'modules/FIRST-SECTION/first-section.module.js',
.........................
your other mappings here
.........................
'lodash': 'npm:lodash/lodash.min.js',
'jquery': 'npm:jquery/dist/jquery.min.js',
},
packages: {
app: { main: './main.js', defaultExtension: 'js' },
rxjs: { defaultExtension: 'js' },
}
});
})(this);
in order to have bundles work for your app, you need to define the "bundles" property for systemjs, something like this:
if (global.ENV === 'production') {
config.transpiler = 'typescript';
config.map = {
'app': 'app',
'@angular': 'node_modules/@angular',
};
config.packages = {
'app': { main: 'main.js', defaultExtension: 'js' },
'@angular/core': { main: 'index.js' },
'@angular/common': { main: 'index.js' },
'@angular/compiler': { main: 'index.js' },
'@angular/forms': { main: 'index.js' },
'@angular/http': { main: 'index.js' },
'@angular/platform-browser': { main: 'index.js' },
'@angular/platform-browser-dynamic': { main: 'index.js' },
'@angular/router': { main: 'index.js' },
};
config.bundles = {
'build/scripts/app.min.js': [
'app/modules/FIRST-SECTION/*',
'app/modules/SECOND-SECTION/*',
'@angular/core/index.js',
'@angular/common/index.js',
'@angular/compiler/index.js',
'@angular/platform-browser/index.js',
'@angular/platform-browser-dynamic/index.js',
'@angular/http/index.js',
'@angular/router/index.js',
'@angular/forms/index.js',
]
}
System.config(config);
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