How to combine (minify) compiled Angular 2 components?

Rivadiz picture Rivadiz · Mar 5, 2016 · Viewed 25.3k times · Source

trying to minify compiled source code of a project for production, I'm using Gulp as the task runner.

the source files look like this,

html

<!--... . .  various scripts and styles . . . . . --->
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>

<script>
  System.config({
    packages: {        
      app: {
        format: 'register',
        defaultExtension: 'js'
      }
    }
  });
  System.import('app/main')
        .then(null, console.error.bind(console));
</script>
</head>
<body>
  <app></app>
</body>

my app directory structure is as follows,

.
├── main.js
├── main.js.map
├── main.ts
├── main.app.js
├── main.app.js.map
├── main.app.ts
├── x.component1
│   ├── x.component.one.js
│   ├── x.component.one.js.map
│   └── x.component.one.ts
└── x.component2
    ├── x.component.two.js
    ├── x.component.two.js.map
    └── x.component.two.ts

app/main.ts

import {bootstrap}    from 'angular2/platform/browser';
import {MyAwesomeApp} from './main.app'

bootstrap(MyAwesomeApp);

main.app.ts

@Component({
    selector: 'app',
    template: `
        <component-1></component-1>

        <component-2></component-2>
    `,
    directives: [Component1, Component2]
})


export class MyAwesomeApp {

}

then the components,

@Component({
    selector: 'component-1',
    template: `
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Beatae ducimus, saepe fugit illum fuga praesentium rem, similique deserunt tenetur laudantium et labore cupiditate veniam qui impedit, earum commodi quasi sequi.
    `
})


export class Component1 {

}

and

@Component({
    selector: 'component-2',
    template: `
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Beatae ducimus, saepe fugit illum fuga praesentium rem, similique deserunt tenetur laudantium et labore cupiditate veniam qui impedit, earum commodi quasi sequi.
    `
})


export class Component2 {

}

All the TypeScript files are compiled down to ES5 JavaScript, further need to minified to main.js

so my questions are,

  1. Can I run a task to collect all the compiled .js files to minify to a single file and reference it as main in production branch?
  2. Does this breaks the module system import {x} from 'y'?
  3. If it breaks the module loading system, what can be done to concatenate files on an Angular 2 application?

my TypeScript version is, 1.8.2

Thank you for any help.

Answer

Thierry Templier picture Thierry Templier · Mar 5, 2016

If you want to compile all your TypeScript files into a single one, you need to use the outFile property of the TypeScript compiler. It's configurable through the gulp-typescript plugin.

This way you don't need to configure SystemJS to load module based on file names:

<script>
  // Not necessary anymore
  /* System.config({
    packages: {        
      app: {
        format: 'register',
        defaultExtension: 'js'
      }
    }
  }); */
  System.import('app/main')
        .then(null, console.error.bind(console));
</script>

The module names and their contents are now present in this single file. The same way for the packaged bundle files of the Angular2 distribution (angular2.dev.js, http.dev.js, ...). To use this file, simply include it in a script element.

This way you won't break module imports.

Then you can minify this single file with the uglify plugin of gulp...