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 { 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 { // es6-promise doesn't have finally() return (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); } }