angular-cn/tools/broccoli/broccoli_builder.ts

91 lines
2.8 KiB
TypeScript

var broccoli = require('broccoli');
var destCopy = require('./broccoli-dest-copy');
var fse = require('fs-extra');
var makeBrowserTree = require('./trees/browser_tree');
var makeNodeTree = require('./trees/node_tree');
var makeDartTree = require('./trees/dart_tree');
var path = require('path');
var printSlowTrees = require('broccoli-slow-trees');
/**
* Helper for building with broccoli.
*/
export class BroccoliBuilder {
private builder;
private broccoliExecuted: {[s: string]: boolean} = {};
// Named constructors
static forDevTree(): BroccoliBuilder {
return new BroccoliBuilder(makeBrowserTree({name: 'dev', typeAssertions: true}),
path.join('js', 'dev'));
}
static forNodeTree(): BroccoliBuilder {
return new BroccoliBuilder(makeNodeTree(), path.join('js', 'cjs'));
}
static forProdTree(): BroccoliBuilder {
return new BroccoliBuilder(makeBrowserTree({name: 'prod', typeAssertions: false}),
path.join('js', 'prod'));
}
static forDartTree(): BroccoliBuilder { return new BroccoliBuilder(makeDartTree(), 'dart'); }
constructor(tree, private outputRoot: string) {
if (this.broccoliExecuted[outputRoot]) {
throw new Error('The broccoli task can be called only once for outputRoot ' + outputRoot);
}
this.broccoliExecuted[outputRoot] = true;
var distPath = path.join('dist', outputRoot);
// We do a clean build every time to avoid stale outputs.
// Broccoli's cache folders allow it to remain incremental without reading this dir.
fse.removeSync(distPath);
tree = destCopy(tree, 'dist');
this.builder = new broccoli.Builder(tree);
}
doBuild(): Promise<any> {
return this.builder.build()
.then(hash =>
{
console.log('=== Stats for %s (total: %ds) ===', this.outputRoot,
Math.round(hash.totalTime / 1000000) / 1000);
printSlowTrees(hash.graph);
})
.catch(err => {
// Should show file and line/col if present
if (err.file) {
console.error('File: ' + err.file);
}
if (err.stack) {
console.error(err.stack);
} else {
console.error(err);
}
throw err;
});
}
buildOnce(): Promise<any> {
// es6-promise doesn't have finally()
return (<any>this.doBuild())
.finally(() =>
{
this.time('Build cleanup', () => this.builder.cleanup());
console.log('=== Done building %s ===', this.outputRoot);
})
.catch(err => {
console.error('\nBuild failed');
process.exit(1);
});
}
time(label, work) {
var start = Date.now();
work();
var duration = Date.now() - start;
console.log("%s: %dms", label, duration);
}
}