angular-docs-cn/tools/broccoli/angular_builder.ts
vsavkin 4e585bca28 feat(build): add an option to disable type checks when running tests
Since editors and IDEs do typechecking and show errors in place,
often there is no benefit to running type checking in our test pipeline.
This PR allows you to disable type checking:

gulp test.unit.js --noTypeChecks

This commit also makes es6 generation optional.

fix(build): removes unnecessary circular dependencies

Closes #5299
2015-11-17 00:45:49 +00:00

163 lines
5.0 KiB
TypeScript

var broccoli = require('broccoli');
var fs = require('fs');
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');
var Q = require('q');
type ProjectMap = {
[key: string]: boolean
};
type Options = {
projects: ProjectMap;
noTypeChecks: boolean;
generateEs6: boolean;
}
;
/**
* BroccoliBuilder facade for all of our build pipelines.
*/
export class AngularBuilder {
private nodeBuilder: BroccoliBuilder;
private browserDevBuilder: BroccoliBuilder;
private browserProdBuilder: BroccoliBuilder;
private dartBuilder: BroccoliBuilder;
private outputPath: string;
private firstResult: BuildResult;
constructor(public options: AngularBuilderOptions) { this.outputPath = options.outputPath; }
public rebuildBrowserDevTree(opts: Options): Promise<BuildResult> {
this.browserDevBuilder = this.browserDevBuilder || this.makeBrowserDevBuilder(opts);
return this.rebuild(this.browserDevBuilder, 'js.dev');
}
public rebuildBrowserProdTree(opts: Options): Promise<BuildResult> {
this.browserProdBuilder = this.browserProdBuilder || this.makeBrowserProdBuilder(opts);
return this.rebuild(this.browserProdBuilder, 'js.prod');
}
public rebuildNodeTree(opts: Options): Promise<BuildResult> {
this.nodeBuilder = this.nodeBuilder || this.makeNodeBuilder(opts.projects);
return this.rebuild(this.nodeBuilder, 'js.cjs');
}
public rebuildDartTree(projects: ProjectMap): Promise<BuildResult> {
this.dartBuilder = this.dartBuilder || this.makeDartBuilder(projects);
return this.rebuild(this.dartBuilder, 'dart');
}
cleanup(): Promise<any> {
return Q.all([
this.nodeBuilder && this.nodeBuilder.cleanup(),
this.browserDevBuilder && this.browserDevBuilder.cleanup(),
this.browserProdBuilder && this.browserProdBuilder.cleanup()
]);
}
private makeBrowserDevBuilder(opts: Options): BroccoliBuilder {
let tree = makeBrowserTree(
{
name: 'dev',
typeAssertions: true,
projects: opts.projects,
noTypeChecks: opts.noTypeChecks,
generateEs6: opts.generateEs6
},
path.join(this.outputPath, 'js', 'dev'));
return new broccoli.Builder(tree);
}
private makeBrowserProdBuilder(opts: Options): BroccoliBuilder {
let tree = makeBrowserTree(
{
name: 'prod',
typeAssertions: false,
projects: opts.projects,
noTypeChecks: opts.noTypeChecks,
generateEs6: opts.generateEs6
},
path.join(this.outputPath, 'js', 'prod'));
return new broccoli.Builder(tree);
}
private makeNodeBuilder(projects: ProjectMap): BroccoliBuilder {
let tree = makeNodeTree(projects, path.join(this.outputPath, 'js', 'cjs'));
return new broccoli.Builder(tree);
}
private makeDartBuilder(projects: ProjectMap): BroccoliBuilder {
let options = {
outputPath: path.join(this.outputPath, 'dart'),
dartSDK: this.options.dartSDK,
logs: this.options.logs,
projects: projects
};
let tree = makeDartTree(options);
return new broccoli.Builder(tree);
}
private rebuild(builder, name) {
return builder.build().then(
(result) => {
if (!this.firstResult) {
this.firstResult = result;
}
printSlowTrees(result.graph);
writeBuildLog(result, name);
},
(error) => {
// the build tree is the same during rebuilds, only leaf properties of the nodes change
// so let's traverse it and get updated values for input/cache/output paths
if (this.firstResult) {
writeBuildLog(this.firstResult, name);
}
throw error;
});
}
}
function writeBuildLog(result: BuildResult, name: string) {
let logPath = `tmp/build.${name}.log`;
let prevLogPath = logPath + '.previous';
let formattedLogContent = JSON.stringify(broccoliNodeToBuildNode(result.graph), null, 2);
if (fs.existsSync(prevLogPath)) fs.unlinkSync(prevLogPath);
if (fs.existsSync(logPath)) fs.renameSync(logPath, prevLogPath);
fs.writeFileSync(logPath, formattedLogContent, {encoding: 'utf-8'});
}
function broccoliNodeToBuildNode(broccoliNode) {
let tree = broccoliNode.tree.newStyleTree || broccoliNode.tree;
return new BuildNode(tree.description || tree.constructor.name,
tree.inputPath ? [tree.inputPath] : tree.inputPaths, tree.cachePath,
tree.outputPath, broccoliNode.selfTime / (1000 * 1000 * 1000),
broccoliNode.totalTime / (1000 * 1000 * 1000),
broccoliNode.subtrees.map(broccoliNodeToBuildNode));
}
class BuildNode {
constructor(public pluginName: string, public inputPaths: string[], public cachePath: string,
public outputPath: string, public selfTime: number, public totalTime: number,
public inputNodes: BroccoliNode[]) {}
}