Angular2, Gulp, SystemJS & # 8594; The problem with the default extension

I am using Angular2 with SystemJS, which worked well during development. Now I wanted to deploy my first compiled version using gulp.

To clarify, I use the following systemJS file:

(function(global) { // map tells the System loader where to look for things var map = { 'app': 'app', // 'dist', 'rxjs': 'lib/node_modules/rxjs', 'angular2-in-memory-web-api': 'lib/node_modules/angular2-in-memory-web-api', '@angular': 'lib/node_modules/@angular', 'ng2-charts/bundles': 'lib/node_modules/ng2-charts/bundles', 'ng2-charts/components': 'lib/node_modules/ng2-charts/components', 'ng2-cookies': 'lib/node_modules/ng2-cookies/' }; // packages tells the System loader how to load when no filename and/or no extension var packages = { 'app': { format: 'register', defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' }, 'angular2-in-memory-web-api': { defaultExtension: 'js' } }; var packageNames = [ '@angular/common', '@angular/compiler', '@angular/core', '@angular/http', '@angular/platform-browser', '@angular/platform-browser-dynamic', '@angular/router', '@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 = { baseURL: "/", defaultJSExtension : true, map: map, packages: packages } // filterSystemConfig - index.html chance to modify config before we register it. if (global.filterSystemConfig) { global.filterSystemConfig(config); } System.config(config); })(this); 

And the following gulpfile file:

 const gulp = require('gulp'); const del = require('del'); const typescript = require('gulp-typescript'); const tscConfig = require('./tsconfig.json'); const tsconfig = require('tsconfig-glob'); const sourcemaps = require('gulp-sourcemaps'); // clean the contents of the distribution directory gulp.task('clean', function () { return del('dist/**/*'); }); // TypeScript compile gulp.task('compile', ['clean'], function () { return gulp .src(tscConfig.files) .pipe(sourcemaps.init()) // <--- sourcemaps .pipe(typescript(tscConfig.compilerOptions)) .pipe(sourcemaps.write('.')) // <--- sourcemaps .pipe(gulp.dest('dist')); }); // copy dependencies gulp.task('copy:libs', ['clean'], function() { return gulp.src([ 'node_modules/angular2/bundles/angular2-polyfills.js', 'node_modules/systemjs/dist/system.src.js', 'node_modules/rxjs/bundles/Rx.js', 'node_modules/angular2/bundles/angular2.dev.js', 'node_modules/angular2/bundles/router.dev.js', 'node_modules/chart.js/dist/Chart.bundle.min.js', 'node_modules/es6-shim/es6-shim.min.js', 'node_modules/zone.js/dist/zone.js', 'node_modules/reflect-metadata/Reflect.js', 'node_modules/systemjs/dist/system.src.js', 'TcAdsWebService.js' ]) .pipe(gulp.dest('dist/lib')) }); gulp.task('copy:modules',['clean'],function() { return gulp.src([ './node_modules/@angular/**/*', './node_modules/rxjs/**/**', './node_modules/angular2-in-memory-web-api/**/*', './node_modules/ng2-charts/**/*', './node_modules/ng2-cookies/**/*' ],{base:'./'}).pipe(gulp.dest('dist/lib')); }); gulp.task('copy:pics',['clean'], function () { return gulp.src(['pics/**/*'],{base:'./'}).pipe(gulp.dest('dist/css')); }) gulp.task('copy:css',['clean'],function() { return gulp.src(['css/**/*'],{base:'./'}).pipe(gulp.dest('dist/css')); }); gulp.task('copy:js',['clean'],function() { return gulp.src(['js/**/*'],{base:'./'}).pipe(gulp.dest('dist/js')); }); gulp.task('copy:systemJS',['clean'],function() { return gulp.src(['systemjs.config.js']).pipe(gulp.dest('dist')); }); // copy static assets - ie non TypeScript compiled source gulp.task('copy:assets', ['clean'], function() { return gulp.src(['app/**/*', 'index.html', 'styles.css', '!app/**/*.ts'], { base : './' }) .pipe(gulp.dest('dist')) }); gulp.task('tsconfig-glob', function () { return tsconfig({ configPath: '.', indent: 2 }); }); gulp.task('build', ['tsconfig-glob','compile', 'copy:pics', 'copy:js', 'copy:css', 'copy:systemJS','copy:modules','copy:libs', 'copy:assets']); gulp.task('default', ['build']); 

After creating the Angular2 application and loading it in the browser, I get the following error in the console:

 Unable to load script http://localhost:81/app/app.component 

which indicates that the .js extension from the compiled files is missing. I sure that

 'app': { format: 'register', defaultExtension: 'js' }, 

should really require the compiler to consider the .js extension in the application folder, however this is not the case. This is my first Angular2 project and my first gulp compiler, and I am sure that I am missing some basic aspect, but I cannot find it in my code.

+5
source share
1 answer

Given your setup, you should use systemjs-builder to associate your application with the product. It accepts your SystemJS configuration, so no further configuration is required. It combines your modules into a single file, with parameters to minimize, cripple, etc.

This makes the "es6 module" way, improving the use of our module loader instead of copying / pasting modules, as it would be in a traditional javascript (es5) application.

Having done this, we can perform dynamic loading from the index page and simply use the script tag specified in the package, it should dramatically speed up the loading time and minimize user loading to load your page. Copying node_modules is also not required.

Given the folder structure:

 src |-- app | |-- main.ts | |-- index.html | |-- bundle.min.js |-- system.config.js |-- node_modules |-- tsconfig.json 

You can even do all this with a single gulp task.

Task: (requires yargs):

 var SystemBuilder = require('systemjs-builder'); var argv = require('yargs').argv; var builder = new SystemBuilder(); gulp.task('bundle', function () { builder.loadConfig('./system.config.js') .then(function () { var outputFile = argv.prod ? './src/app/bundle.min.js' : './src/app/bundle.js'; return builder.buildStatic('app', outputFile, { minify: argv.prod, mangle: argv.prod, rollup: argv.prod }); }) .then(function () { console.log('bundle built successfully!'); }); }); 

Run this task:

 gulp bundle 

or

 gulp bundle --prod 

index.html

 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <base href="/" /> <title>Your App</title> <link rel="stylesheet" href='styles/bootstrap.min.css' /> <script src="/bundle.js"></script> </head> <body> <your-root-component> </your-root-component> </body> </html> 

system.config.js:

 (function (global) { var config = { compiler: "typescript", map: { 'jquery': 'node_modules/jquery/dist', 'bootstrap': 'node_modules/bootstrap/dist/js', "reflect-metadata": "node_modules/reflect-metadata", "zone": "node_modules/zone.js/dist", "crypto": "node_modules/crypto", 'rxjs': 'node_modules/rxjs', 'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api', '@angular': 'node_modules/@angular', 'moment': 'node_modules/moment', 'angular2-moment': 'node_modules/angular2-moment', 'app': 'src/app', }, meta: { 'node_modules/bootstrap/dist/js/bootstrap.js': { format: 'global', deps: ['jquery'] } }, packages: { 'jquery': { main: 'jquery.js', defaultExtension: 'js' }, 'bootstrap': { main: 'bootstrap.js', defaultExtension: 'js' }, 'zone': { main: 'zone.js', defaultExtension: 'js' }, 'reflect-metadata': { main: 'Reflect.js', defaultExtension: 'js' }, 'crypto': { main: 'sha1.js', defaultExtension: 'js' }, 'rxjs': { main: 'Rx.js', defaultExtension: 'js' }, 'moment':{main: 'moment.js', defaultExtension: 'js'}, 'angular2-moment': { main: 'index.js', defaultExtension: 'js' }, 'app': { main: 'main.js', defaultExtension: 'js' }, '@angular/common': { main: 'index.js', defaultExtension: 'js' }, '@angular/compiler': { main: 'index.js', defaultExtension: 'js' }, '@angular/core': { main: 'index.js', defaultExtension: 'js' }, '@angular/http': { main: 'index.js', defaultExtension: 'js' }, '@angular/platform-browser': { main: 'index.js', defaultExtension: 'js' }, '@angular/platform-browser-dynamic': { main: 'index.js', defaultExtension: 'js' }, '@angular/router': { main: 'index.js', defaultExtension: 'js' }, '@angular/testing': { main: 'index.js', defaultExtension: 'js' }, '@angular/upgrade': { main: 'index.js', defaultExtension: 'js' }, '@angular/forms': { main: 'index.js', defaultExtension: 'js' }, } } System.config(config); })(this); 

With all that said: I believe your package section:

  var packages = { 'app': { format: 'register', defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' }, 'angular2-in-memory-web-api': { defaultExtension: 'js' } }; 

it should be:

  var packages = { 'app': { main: 'main.js', defaultExtension: 'js' }, 'rxjs': { main: 'Rx.js', defaultExtension: 'js' }, 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' } }; 

main.js is any file containing your bootstrap function for angular2.

+4
source

All Articles