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)
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:
app.js
filevendor.js
file for third-party librariesboot.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).index.html
to take into account these two filesThe following dependencies are used in the gulp tasks:
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.