Build Angular2 HTML and TypeScript to a single file
If you're using the default Angular2 tsconfig.json
with SystemJS loader:
"module": "system",
"moduleResolution": "node",
...
You can leave all the heavy work on SystemJS Build Tool. This is for example how I do it in my projects using gulp
:
-
Compile *.ts and inline *.html templates
I'm using
gulp-angular-embed-templates
right away to inline alltemplateUrl
intotemplate
strings (this plugin works with both Angular 1.* and Angular 2).var tsc = require('gulp-typescript'); var tsProject = tsc.createProject('tsconfig.json'); var embedTemplates = require('gulp-angular-embed-templates'); gulp.task('app.build', function () { var tsResult = gulp.src('app/src/**/*.ts', {base: './app/src'}) .pipe(embedTemplates()) // inline templates .pipe(tsc(tsProject)); return tsResult.js .pipe(gulp.dest('build/js')); });
This will generate many anonymous System.register modules in
build/js
directory. All of them will have theirtemplateUrl
inlined already. -
Bundle everything into a single
.js
fileI use SystemJS Build Tool for this because I think it's way easier than using for example webpack. So, I have another gulp task for this to automate the process:
var SystemBuilder = require('systemjs-builder'); gulp.task('app.systemjs.bundle', function () { var builder = new SystemBuilder('build/js, { paths: { '*': '*.js' }, meta: { 'angular2/*': { build: false }, 'rxjs/*': { build: false } } }); return builder.bundle('main', 'build/js/app.bundle.js'); });
The builder takes the same options as SystemJS so check their Config API.
Calling
builder.bundle('main', ...)
searches formain.js
(which is my initial script with Angular'sbootstrap
call. It's the same file you can see in the 5 min quickstart) because I append.js
to all paths searched by the builder. This is because when you import a module in TS you usually call:import {ModalResultComponent} from './modal-result.component';
which is compiled as
./modal-result.component
dependency and it doesn't care about the file extension. That's why I had to add*.js
to all paths to help builder find all compiled JavaScript files.The
meta
options just tell the builder to ignore dependencies that I don't want to bundle. That's Angular2 itself andrxjs
library because I includeimport 'rxjs/add/operator/map'
inmain.ts
.This generates a single
app.bundle.js
file with all modules registered as named modules using System.register. -
Using our
app.bundle.js
The last part is a piece of cake. We just import the default Angular2 stuff and then use
bundle
option to tell SystemJS where're all our dependencies.<script> System.config({ packages: { '/web': { format: 'register', defaultExtension: 'js' } }, bundles: { '/web/app.bundle': ['main'] } }); System.import('main').then(null, console.error.bind(console)); </script>
When we call
System.import('main')
it in fact first downloads/web/app.bundle.js
and registers all modules in the package and after that it imports modulesmain
with our Angular2 bootstrap.And that's it!
You actually don't need to use gulp
at all and do everything with pure node
script.
Bundling CSS files is easy with things like cssnano and I'm sure you can find tutorials on how to use it everywhere.
I'm sure there're other ways to the the same thing. Angular2 is designed not to restrict you to use just one technology. However, using SystemJS seems to me to be the easiest way because it uses the same module system as Angular2 by default.
I'm sure you could use also for example commonjs
format but that would require you to use also some polyfill for require()
loader, but I haven't tried it yet. I belive UMD might be also worth trying.