Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I actually deploy an Angular 2 + Typescript + systemjs app?

There's a quickstarter tutorial over at angular.io which uses typescript & systemjs. Now that I've got that miniapp running, how would I go about creating something deployable? I couldn't find any info about it whatsoever.

Do I need any extra tools, any additional settings in System.config?

(I know that I could use webpack & create a single bundle.js, but I'd like to use systemjs as it is used in the tutorial)

Could someone share their build process with this setup (Angular 2, TypeScript, systemjs)

like image 469
Brian G. Bell Avatar asked Mar 29 '16 13:03

Brian G. Bell


People also ask

How is Angular application deployed?

Basic deployment to a remote serverlink For the simplest deployment, create a production build and copy the output directory to a web server. Copy everything within the output folder ( dist/project-name/ by default) to a folder on the server. Configure the server to redirect requests for missing files to index.html .

What is the best server to deploy Angular app?

Because these files are static, you can host them on any web server capable of serving files; such as Node. js , Java, . NET, or any backend such as Firebase, Google Cloud, or App Engine.

What is SystemJS in Angular?

systemjs.config.js. It contains the mapping information of files, which are used for developing Angular application. It tells the SystemJS module loader where to find modules referenced in Angular component imports statements.


2 Answers

The key thing to understand at this level is that using the following configuration, you can't concat compiled JS files directly.

At the TypeScript compiler configuration:

{   "compilerOptions": {     "emitDecoratorMetadata": true,     "experimentalDecorators": true,     "declaration": false,     "stripInternal": true,     "module": "system",     "moduleResolution": "node",     "noEmitOnError": false,     "rootDir": ".",     "inlineSourceMap": true,     "inlineSources": true,     "target": "es5"   },   "exclude": [     "node_modules"   ] } 

In the HTML

System.config({   packages: {     app: {       defaultExtension: 'js',       format: 'register'     }   } }); 

As a matter of fact, these JS files will contain anonymous modules. An anonymous module is a JS file that uses System.register but without the module name as first parameter. This is what the typescript compiler generates by default when systemjs is configured as module manager.

So to have all your modules into a single JS file, you need to leverage the outFile property within your TypeScript compiler configuration.

You can use the following inside gulp to do that:

const gulp = require('gulp'); const ts = require('gulp-typescript');  var tsProject = ts.createProject('tsconfig.json', {   typescript: require('typescript'),   outFile: 'app.js' });  gulp.task('tscompile', function () {   var tsResult = gulp.src('./app/**/*.ts')                      .pipe(ts(tsProject));    return tsResult.js.pipe(gulp.dest('./dist')); }); 

This could be combined with some other processing:

  • to uglify things the compiled TypeScript files
  • to create an app.js file
  • to create a vendor.js file for third-party libraries
  • to create a boot.js file to import the module that bootstrap the application. This file must be included at the end of the page (when all the page is loaded).
  • to update the index.html to take into account these two files

The following dependencies are used in the gulp tasks:

  • gulp-concat
  • gulp-html-replace
  • gulp-typescript
  • gulp-uglify

The following is a sample so it could be adapted.

  • Create app.min.js file

    gulp.task('app-bundle', function () {   var tsProject = ts.createProject('tsconfig.json', {     typescript: require('typescript'),     outFile: 'app.js'   });    var tsResult = gulp.src('app/**/*.ts')                    .pipe(ts(tsProject));    return tsResult.js.pipe(concat('app.min.js'))                 .pipe(uglify())                 .pipe(gulp.dest('./dist')); }); 
  • Create vendors.min.js file

    gulp.task('vendor-bundle', function() {   gulp.src([     'node_modules/es6-shim/es6-shim.min.js',     'node_modules/systemjs/dist/system-polyfills.js',     '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/http.dev.js'   ])   .pipe(concat('vendors.min.js'))   .pipe(uglify())   .pipe(gulp.dest('./dist')); }); 
  • Create boot.min.js file

    gulp.task('boot-bundle', function() {   gulp.src('config.prod.js')     .pipe(concat('boot.min.js'))     .pipe(uglify())     .pipe(gulp.dest('./dist'));  }); 

    The config.prod.js simply contains the following:

     System.import('boot')     .then(null, console.error.bind(console)); 
  • Update the index.html file

    gulp.task('html', function() {   gulp.src('index.html')     .pipe(htmlreplace({       'vendor': 'vendors.min.js',       'app': 'app.min.js',       'boot': 'boot.min.js'     }))     .pipe(gulp.dest('dist')); }); 

    The index.html looks like the following:

    <html>   <head>     <!-- Some CSS -->      <!-- build:vendor -->     <script src="node_modules/es6-shim/es6-shim.min.js"></script>     <script src="node_modules/systemjs/dist/system-polyfills.js"></script>     <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>     <script src="node_modules/systemjs/dist/system.src.js"></script>     <script src="node_modules/rxjs/bundles/Rx.js"></script>     <script src="node_modules/angular2/bundles/angular2.dev.js"></script>     <script src="node_modules/angular2/bundles/http.dev.js"></script>     <!-- endbuild -->      <!-- build:app -->     <script src="config.js"></script>     <!-- endbuild -->   </head>    <body>     <my-app>Loading...</my-app>      <!-- build:boot -->     <!-- endbuild -->   </body> </html> 

Notice that the System.import('boot'); must be done at the end of the body to wait for all your app components to be registered from the app.min.js file.

I don't describe here the way to handle CSS and HTML minification.

like image 171
Thierry Templier Avatar answered Oct 22 '22 08:10

Thierry Templier


You can use angular2-cli build command

ng build -prod 

https://github.com/angular/angular-cli/wiki/build#bundling

Builds created with the -prod flag via ng build -prod or ng serve -prod bundle all dependencies into a single file, and make use of tree-shaking techniques.

Update

This answer was submitted when angular2 was in rc4

I had tried it again on angular-cli beta21 and angular2 ^2.1.0 and it is working as expected

This answer requires initializing the app with angular-cli you can use

ng new myApp 

Or on an existing one

ng init 

Update 08/06/2018

For angular 6 the syntax is different.

ng build --prod --build-optimizer 

Check the documentation

like image 26
Amr ElAdawy Avatar answered Oct 22 '22 08:10

Amr ElAdawy