refactor(@angular-devkit/build-angular): allow control of cache location

`NG_BUILD_CACHE` can specify an absolute path to be used as the cache location.  Caching can also be disabled by setting the variable to 0 or false.
This commit is contained in:
Charles Lyding 2019-10-21 12:25:32 -04:00 committed by vikerman
parent 5260bbb9a3
commit 5597f7fedc
8 changed files with 78 additions and 34 deletions

View File

@ -26,7 +26,8 @@ import {
import { RawSource } from 'webpack-sources';
import { AssetPatternClass, ExtraEntryPoint } from '../../../browser/schema';
import { BuildBrowserFeatures } from '../../../utils';
import { manglingDisabled } from '../../../utils/mangle-options';
import { findCachePath } from '../../../utils/cache-path';
import { cachingDisabled, manglingDisabled } from '../../../utils/environment-options';
import { BundleBudgetPlugin } from '../../plugins/bundle-budget';
import { CleanCssWebpackPlugin } from '../../plugins/cleancss-webpack-plugin';
import { NamedLazyChunksPlugin } from '../../plugins/named-chunks-plugin';
@ -411,7 +412,7 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
new TerserPlugin({
sourceMap: scriptsSourceMap,
parallel: true,
cache: true,
cache: !cachingDisabled && findCachePath('terser-webpack'),
extractComments: false,
chunkFilter: (chunk: compilation.Chunk) =>
!globalScriptsByBundleName.some(s => s.bundleName === chunk.name),
@ -422,7 +423,7 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
new TerserPlugin({
sourceMap: scriptsSourceMap,
parallel: true,
cache: true,
cache: !cachingDisabled && findCachePath('terser-webpack'),
extractComments: false,
chunkFilter: (chunk: compilation.Chunk) =>
globalScriptsByBundleName.some(s => s.bundleName === chunk.name),

View File

@ -6,14 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
import { createHash } from 'crypto';
import * as findCacheDirectory from 'find-cache-dir';
import * as fs from 'fs';
import { copyFile } from '../utils/copy-file';
import { manglingDisabled } from '../utils/mangle-options';
import { manglingDisabled } from '../utils/environment-options';
import { CacheKey, ProcessBundleOptions, ProcessBundleResult } from '../utils/process-bundle';
const cacache = require('cacache');
const cacheDownlevelPath = findCacheDirectory({ name: 'angular-build-dl' });
const packageVersion = require('../../package.json').version;
export interface CacheEntry {
@ -23,7 +21,7 @@ export interface CacheEntry {
}
export class BundleActionCache {
constructor(private readonly integrityAlgorithm?: string) {}
constructor(private readonly cachePath: string, private readonly integrityAlgorithm?: string) {}
static copyEntryContent(entry: CacheEntry | string, dest: fs.PathLike): void {
copyFile(typeof entry === 'string' ? entry : entry.path, dest);
@ -88,7 +86,7 @@ export class BundleActionCache {
const cacheEntries = [];
for (const key of cacheKeys) {
if (key) {
const entry = await cacache.get.info(cacheDownlevelPath, key);
const entry = await cacache.get.info(this.cachePath, key);
if (!entry) {
return false;
}

View File

@ -9,6 +9,7 @@ import JestWorker from 'jest-worker';
import * as os from 'os';
import * as path from 'path';
import * as v8 from 'v8';
import { I18nOptions } from '../utils/i18n-options';
import { InlineOptions, ProcessBundleOptions, ProcessBundleResult } from '../utils/process-bundle';
import { BundleActionCache } from './action-cache';
@ -36,14 +37,16 @@ workerFile =
export class BundleActionExecutor {
private largeWorker?: JestWorker;
private smallWorker?: JestWorker;
private cache: BundleActionCache;
private cache?: BundleActionCache;
constructor(
private workerOptions: unknown,
private workerOptions: { cachePath?: string; i18n: I18nOptions },
integrityAlgorithm?: string,
private readonly sizeThreshold = 32 * 1024,
) {
this.cache = new BundleActionCache(integrityAlgorithm);
if (workerOptions.cachePath) {
this.cache = new BundleActionCache(workerOptions.cachePath, integrityAlgorithm);
}
}
private static executeMethod<O>(worker: JestWorker, method: string, input: unknown): Promise<O> {
@ -87,16 +90,18 @@ export class BundleActionExecutor {
}
async process(action: ProcessBundleOptions): Promise<ProcessBundleResult> {
const cacheKeys = this.cache.generateCacheKeys(action);
action.cacheKeys = cacheKeys;
if (this.cache) {
const cacheKeys = this.cache.generateCacheKeys(action);
action.cacheKeys = cacheKeys;
// Try to get cached data, if it fails fallback to processing
try {
const cachedResult = await this.cache.getCachedBundleResult(action);
if (cachedResult) {
return cachedResult;
}
} catch {}
// Try to get cached data, if it fails fallback to processing
try {
const cachedResult = await this.cache.getCachedBundleResult(action);
if (cachedResult) {
return cachedResult;
}
} catch {}
}
return this.executeAction<ProcessBundleResult>('process', action);
}
@ -107,7 +112,7 @@ export class BundleActionExecutor {
async inline(
action: InlineOptions,
): Promise<{ file: string; diagnostics: { type: string; message: string }[]; count: number; }> {
): Promise<{ file: string; diagnostics: { type: string; message: string }[]; count: number }> {
return this.executeAction('inlineLocales', action);
}

View File

@ -9,7 +9,6 @@ import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/ar
import { EmittedFiles, WebpackLoggingCallback, runWebpack } from '@angular-devkit/build-webpack';
import { join, json, logging, normalize, tags, virtualFs } from '@angular-devkit/core';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import * as findCacheDirectory from 'find-cache-dir';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
@ -50,7 +49,9 @@ import {
normalizeOptimization,
normalizeSourceMaps,
} from '../utils';
import { findCachePath } from '../utils/cache-path';
import { copyAssets } from '../utils/copy-assets';
import { cachingDisabled } from '../utils/environment-options';
import { emittedFilesToInlineOptions } from '../utils/i18n-inlining';
import { I18nOptions, createI18nOptions, mergeDeprecatedI18nOptions } from '../utils/i18n-options';
import { createTranslationLoader } from '../utils/load-translations';
@ -69,7 +70,7 @@ import {
import { BundleActionExecutor } from './action-executor';
import { Schema as BrowserBuilderSchema } from './schema';
const cacheDownlevelPath = findCacheDirectory({ name: 'angular-build-dl' });
const cacheDownlevelPath = cachingDisabled ? undefined : findCachePath('angular-build-dl');
export type BrowserBuilderOutput = json.JsonObject &
BuilderOutput & {

View File

@ -0,0 +1,19 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as findCacheDirectory from 'find-cache-dir';
import { tmpdir } from 'os';
import { resolve } from 'path';
import { cachingBasePath } from './environment-options';
export function findCachePath(name: string): string {
if (cachingBasePath) {
return resolve(cachingBasePath, name);
}
return findCacheDirectory({ name }) || tmpdir();
}

View File

@ -0,0 +1,30 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as path from 'path';
const mangleVariable = process.env['NG_BUILD_MANGLE'];
export const manglingDisabled =
!!mangleVariable && (mangleVariable === '0' || mangleVariable.toLowerCase() === 'false');
const cacheVariable = process.env['NG_BUILD_CACHE'];
export const cachingDisabled =
!!cacheVariable && (cacheVariable === '0' || cacheVariable.toLowerCase() === 'false');
export const cachingBasePath = (() => {
if (
cachingDisabled ||
!cacheVariable ||
(cacheVariable === '1' || cacheVariable.toLowerCase() === 'true')
) {
return null;
}
if (!path.isAbsolute(cacheVariable)) {
throw new Error('NG_BUILD_CACHE path value must be absolute.');
}
return cacheVariable;
})();

View File

@ -1,10 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
const mangleVariable = process.env['NG_BUILD_MANGLE'];
export const manglingDisabled =
!!mangleVariable && (mangleVariable === '0' || mangleVariable.toLowerCase() === 'false');

View File

@ -13,8 +13,8 @@ import { RawSourceMap, SourceMapConsumer, SourceMapGenerator } from 'source-map'
import { minify } from 'terser';
import * as v8 from 'v8';
import { SourceMapSource } from 'webpack-sources';
import { manglingDisabled } from './environment-options';
import { I18nOptions } from './i18n-options';
import { manglingDisabled } from './mangle-options';
const cacache = require('cacache');
const deserialize = ((v8 as unknown) as { deserialize(buffer: Buffer): unknown }).deserialize;