Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/angular_devkit/build_angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@angular-devkit/build-webpack": "0.0.0",
"@angular-devkit/core": "0.0.0",
"@babel/core": "7.6.4",
"@babel/generator": "7.6.4",
"@babel/preset-env": "7.6.3",
"@ngtools/webpack": "0.0.0",
"ajv": "6.10.2",
Expand All @@ -33,6 +34,7 @@
"less-loader": "5.0.0",
"license-webpack-plugin": "2.1.3",
"loader-utils": "1.2.3",
"magic-string": "0.25.4",
"mini-css-extract-plugin": "0.8.0",
"minimatch": "3.0.4",
"parse5": "4.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,25 @@
import JestWorker from 'jest-worker';
import * as os from 'os';
import * as path from 'path';
import { ProcessBundleOptions, ProcessBundleResult } from '../utils/process-bundle';
import * as v8 from 'v8';
import { InlineOptions, ProcessBundleOptions, ProcessBundleResult } from '../utils/process-bundle';
import { BundleActionCache } from './action-cache';

const hasThreadSupport = (() => {
try {
require('worker_threads');

return true;
} catch {
return false;
}
})();

// This is used to normalize serialization messaging across threads and processes
// Threads use the structured clone algorithm which handles more types
// Processes use JSON which is much more limited
const serialize = ((v8 as unknown) as { serialize(value: unknown): Buffer }).serialize;

let workerFile = require.resolve('../utils/process-bundle');
workerFile =
path.extname(workerFile) === '.ts'
Expand Down Expand Up @@ -41,8 +57,8 @@ export class BundleActionExecutor {

// larger files are processed in a separate process to limit memory usage in the main process
return (this.largeWorker = new JestWorker(workerFile, {
exposedMethods: ['process'],
setupArgs: [this.workerOptions],
exposedMethods: ['process', 'inlineLocales'],
setupArgs: [[...serialize(this.workerOptions)]],
}));
}

Expand All @@ -54,11 +70,10 @@ export class BundleActionExecutor {
// small files are processed in a limited number of threads to improve speed
// The limited number also prevents a large increase in memory usage for an otherwise short operation
return (this.smallWorker = new JestWorker(workerFile, {
exposedMethods: ['process'],
setupArgs: [this.workerOptions],
exposedMethods: ['process', 'inlineLocales'],
setupArgs: hasThreadSupport ? [this.workerOptions] : [[...serialize(this.workerOptions)]],
numWorkers: os.cpus().length < 2 ? 1 : 2,
// Will automatically fallback to processes if not supported
enableWorkerThreads: true,
enableWorkerThreads: hasThreadSupport,
}));
}

Expand All @@ -71,7 +86,7 @@ export class BundleActionExecutor {
}
}

async process(action: ProcessBundleOptions) {
async process(action: ProcessBundleOptions): Promise<ProcessBundleResult> {
const cacheKeys = this.cache.generateCacheKeys(action);
action.cacheKeys = cacheKeys;

Expand All @@ -86,10 +101,27 @@ export class BundleActionExecutor {
return this.executeAction<ProcessBundleResult>('process', action);
}

async *processAll(actions: Iterable<ProcessBundleOptions>) {
const executions = new Map<Promise<ProcessBundleResult>, Promise<ProcessBundleResult>>();
processAll(actions: Iterable<ProcessBundleOptions>): AsyncIterable<ProcessBundleResult> {
return BundleActionExecutor.executeAll(actions, action => this.process(action));
}

async inline(
action: InlineOptions,
): Promise<{ file: string; diagnostics: { type: string; message: string }[]; count: number; }> {
return this.executeAction('inlineLocales', action);
}

inlineAll(actions: Iterable<InlineOptions>) {
return BundleActionExecutor.executeAll(actions, action => this.inline(action));
}

private static async *executeAll<I, O>(
actions: Iterable<I>,
executor: (action: I) => Promise<O>,
): AsyncIterable<O> {
const executions = new Map<Promise<O>, Promise<O>>();
for (const action of actions) {
const execution = this.process(action);
const execution = executor(action);
executions.set(
execution,
execution.then(result => {
Expand All @@ -105,7 +137,7 @@ export class BundleActionExecutor {
}
}

stop() {
stop(): void {
if (this.largeWorker) {
this.largeWorker.end();
}
Expand Down
Loading