build: ngc-wrapped as a bazel worker (#18960)

PR Close #18960
This commit is contained in:
Alex Eagle 2017-08-29 22:09:55 -07:00 committed by Miško Hevery
parent 56238fe94e
commit fef3d2ad53
9 changed files with 84 additions and 35 deletions

View File

@ -1,6 +1,18 @@
# Disable sandboxing because it's too slow. # Make compilation fast, by keeping a few copies of the compilers
# https://github.com/bazelbuild/bazel/issues/2424 # running as daemons, and cache SourceFile AST's to reduce parse time.
build --spawn_strategy=standalone build --strategy=TypeScriptCompile=worker
build --strategy=AngularTemplateCompile=worker
# Don't create bazel-* symlinks in the WORKSPACE directory.
# These require .gitignore and may scare users.
# Also, it's a workaround for https://github.com/bazelbuild/rules_typescript/issues/12
# which affects the common case of having `tsconfig.json` in the WORKSPACE directory.
#
# Instead, you should run `bazel info bazel-bin` to find out where the outputs went.
build --symlink_prefix=/
# Performance: avoid stat'ing input files # Performance: avoid stat'ing input files
build --watchfs build --watchfs
# Don't print all the .d.ts output locations after builds
build --show_result=0

View File

@ -6,20 +6,25 @@ exports_files(["tsconfig.json"])
# https://github.com/bazelbuild/bazel/issues/374#issuecomment-296217940 # https://github.com/bazelbuild/bazel/issues/374#issuecomment-296217940
filegroup( filegroup(
name = "node_modules", name = "node_modules",
srcs = glob([ # Performance workaround: list individual files
# Performance workaround: list individual files # Reduces the number of files as inputs to nodejs_binary:
# This won't scale in the general case. # bazel query "deps(:node_modules)" | wc -l
# TODO(alexeagle): figure out what to do # This won't scale in the general case.
"node_modules/typescript/**", # TODO(alexeagle): figure out what to do
"node_modules/zone.js/**", srcs = glob(["/".join(["node_modules", pkg, "**", ext]) for pkg in [
"node_modules/rxjs/**/*.d.ts", "typescript",
"node_modules/rxjs/**/*.js", "zone.js",
"node_modules/@types/**/*.d.ts", "rxjs",
"node_modules/tsickle/**", "@types",
"node_modules/hammerjs/**/*.d.ts", "tsickle",
"node_modules/protobufjs/**", "hammerjs",
"node_modules/bytebuffer/**", "protobufjs",
"node_modules/reflect-metadata/**", "bytebuffer",
"node_modules/minimist/**/*.js", "reflect-metadata",
]), "minimist",
] for ext in [
"*.js",
"*.json",
"*.d.ts",
]]),
) )

View File

@ -15,7 +15,6 @@
"devDependencies": { "devDependencies": {
"@angular/bazel": "file:../../dist/packages-dist/bazel", "@angular/bazel": "file:../../dist/packages-dist/bazel",
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli", "@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
"@bazel/typescript": "0.0.7",
"typescript": "~2.3.1" "typescript": "~2.3.1"
}, },
"scripts": { "scripts": {

View File

@ -3,7 +3,7 @@
"version": "5.0.0-beta.5", "version": "5.0.0-beta.5",
"dependencies": { "dependencies": {
"@bazel/typescript": { "@bazel/typescript": {
"version": "0.0.7", "version": "0.0.9",
"dependencies": { "dependencies": {
"@types/node": { "@types/node": {
"version": "7.0.18" "version": "7.0.18"

6
npm-shrinkwrap.json generated
View File

@ -3,9 +3,9 @@
"version": "5.0.0-beta.5", "version": "5.0.0-beta.5",
"dependencies": { "dependencies": {
"@bazel/typescript": { "@bazel/typescript": {
"version": "0.0.7", "version": "0.0.9",
"from": "@bazel/typescript@0.0.7", "from": "@bazel/typescript@latest",
"resolved": "https://registry.npmjs.org/@bazel/typescript/-/typescript-0.0.7.tgz", "resolved": "https://registry.npmjs.org/@bazel/typescript/-/typescript-0.0.9.tgz",
"dependencies": { "dependencies": {
"@types/node": { "@types/node": {
"version": "7.0.18", "version": "7.0.18",

View File

@ -9,7 +9,7 @@
"typescript": "~2.3" "typescript": "~2.3"
}, },
"dependencies": { "dependencies": {
"@bazel/typescript": "~0.0.7" "@bazel/typescript": "0.0.9"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -173,8 +173,7 @@ NG_MODULE_ATTRIBUTES = {
cfg = "host", cfg = "host",
), ),
# TODO(alexeagle): enable workers for ngc "_supports_workers": attr.bool(default = True),
"_supports_workers": attr.bool(default = False),
} }
ng_module = rule( ng_module = rule(

View File

@ -22,6 +22,10 @@ nodejs_binary(
# Entry point assumes the user is outside this WORKSPACE, # Entry point assumes the user is outside this WORKSPACE,
# and references our rules with @angular//src/ngc-wrapped # and references our rules with @angular//src/ngc-wrapped
entry_point = "angular/src/ngc-wrapped/index.js", entry_point = "angular/src/ngc-wrapped/index.js",
data = [":ngc_lib"], args = ["--node_options=--expose-gc"],
data = [
":ngc_lib",
"@build_bazel_rules_typescript//internal:worker_protocol.proto"
],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import * as ng from '@angular/compiler-cli'; import * as ng from '@angular/compiler-cli';
import {CompilerHost, UncachedFileLoader, parseTsconfig} from '@bazel/typescript'; import {CachedFileLoader, CompilerHost, FileCache, FileLoader, UncachedFileLoader, debug, parseTsconfig, runAsWorker, runWorkerLoop} from '@bazel/typescript';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as tsickle from 'tsickle'; import * as tsickle from 'tsickle';
@ -19,6 +19,10 @@ const NGC_NON_TS_INPUTS =
/(\.(ngsummary|ngstyle|ngfactory)(\.d)?\.ts|\.ngsummary\.json|\.css|\.html)$/; /(\.(ngsummary|ngstyle|ngfactory)(\.d)?\.ts|\.ngsummary\.json|\.css|\.html)$/;
// FIXME should need only summary, css, html // FIXME should need only summary, css, html
// TODO(alexeagle): probably not needed, see
// https://github.com/bazelbuild/rules_typescript/issues/28
const ALLOW_NON_HERMETIC_READS = true;
function topologicalSort( function topologicalSort(
result: tsickle.FileMap<boolean>, current: string, modulesManifest: tsickle.ModulesManifest, result: tsickle.FileMap<boolean>, current: string, modulesManifest: tsickle.ModulesManifest,
visiting: tsickle.FileMap<boolean>) { visiting: tsickle.FileMap<boolean>) {
@ -53,7 +57,28 @@ export function constructManifest(
} }
export function main(args) { export function main(args) {
const project = args[1]; if (runAsWorker(args)) {
runWorkerLoop(runOneBuild);
} else {
return runOneBuild(args) ? 0 : 1;
}
return 0;
}
/** The one FileCache instance used in this process. */
const fileCache = new FileCache<ts.SourceFile>(debug);
function runOneBuild(args: string[], inputs?: {[path: string]: string}): boolean {
if (args[0] === '-p') args.shift();
// Strip leading at-signs, used to indicate a params file
const project = args[0].replace(/^@+/, '');
let fileLoader: FileLoader;
if (inputs) {
fileLoader = new CachedFileLoader(fileCache, ALLOW_NON_HERMETIC_READS);
fileCache.updateCache(inputs);
} else {
fileLoader = new UncachedFileLoader();
}
const [{options: tsOptions, bazelOpts, files, config}] = parseTsconfig(project); const [{options: tsOptions, bazelOpts, files, config}] = parseTsconfig(project);
const {basePath} = ng.calcProjectFileAndBasePath(project); const {basePath} = ng.calcProjectFileAndBasePath(project);
@ -72,7 +97,7 @@ export function main(args) {
// NB: the rootDirs should have been sorted longest-first // NB: the rootDirs should have been sorted longest-first
for (const dir of rootDirs || []) { for (const dir of rootDirs || []) {
const rel = path.relative(dir, filePath); const rel = path.relative(dir, filePath);
if (rel.indexOf('.') != 0) return rel; if (rel.indexOf('.') !== 0) return rel;
} }
return filePath; return filePath;
} }
@ -121,9 +146,14 @@ export function main(args) {
} }
const bazelHost = new CompilerHost( const bazelHost = new CompilerHost(
files, tsOptions, bazelOpts, tsHost, new UncachedFileLoader(), generatedFileModuleResolver); files, tsOptions, bazelOpts, tsHost, fileLoader, ALLOW_NON_HERMETIC_READS,
bazelHost.allowNonHermeticRead = (filePath: string) => generatedFileModuleResolver);
NGC_NON_TS_INPUTS.test(filePath) || filePath.split(path.sep).indexOf('node_modules') != -1; // The file cache is populated by Bazel with workspace-relative filenames
// so we must relativize paths before looking them up in the cache.
const originalGetSourceFile = bazelHost.getSourceFile.bind(bazelHost);
bazelHost.getSourceFile = (fileName: string, languageVersion: ts.ScriptTarget) => {
return originalGetSourceFile(relativeToRootDirs(fileName, [tsOptions.rootDir]));
};
bazelHost.shouldSkipTsickleProcessing = (fileName: string): boolean => bazelHost.shouldSkipTsickleProcessing = (fileName: string): boolean =>
bazelOpts.compilationTargetSrc.indexOf(fileName) === -1 && !NGC_NON_TS_INPUTS.test(fileName); bazelOpts.compilationTargetSrc.indexOf(fileName) === -1 && !NGC_NON_TS_INPUTS.test(fileName);
@ -185,7 +215,7 @@ export function main(args) {
originalWriteFile(missing, '', false); originalWriteFile(missing, '', false);
} }
return diagnostics.some(d => d.category === ts.DiagnosticCategory.Error) ? 1 : 0; return diagnostics.every(d => d.category !== ts.DiagnosticCategory.Error);
} }
if (require.main === module) { if (require.main === module) {