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
31 changes: 31 additions & 0 deletions packages/angular/build/src/tools/esbuild/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Provides infrastructure for common caching functionality within the build system.
*/

import { persistentCacheStoreSetting } from '../../utils/environment-options';
import { assertIsError } from '../../utils/error';

/**
Expand Down Expand Up @@ -248,6 +249,36 @@ export class MemoryCache<V> extends Cache<V, Map<string, V>> {
export async function createPersistentCacheStore(
baseCachePath: string,
): Promise<PersistentCacheStore> {
if (persistentCacheStoreSetting === 'sqlite') {
try {
const { SqliteCacheStore } = await import('./sqlite-cache-store');

return new SqliteCacheStore(baseCachePath + '-sqlite.db');
} catch (err) {
assertIsError(err);

throw new Error(
'Unable to initialize JavaScript cache storage.\n' + `SQLite error: ${err.message}`,
{ cause: err },
);
}
}

if (persistentCacheStoreSetting === 'lmdb') {
try {
const { LmdbCacheStore } = await import('./lmdb-cache-store');

return new LmdbCacheStore(baseCachePath + '.db');
} catch (err) {
assertIsError(err);

throw new Error(
'Unable to initialize JavaScript cache storage.\n' + `LMDB error: ${err.message}`,
{ cause: err },
);
}
}

try {
const { LmdbCacheStore } = await import('./lmdb-cache-store');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,68 @@ describe('SqliteCacheStore', () => {
expect(checkStore.has('k1')).toBeFalse();
checkStore.close();
});

describe('NG_BUILD_CACHE_STORE env variable option', () => {
it('should force SQLite when NG_BUILD_CACHE_STORE=sqlite', () => {
const code = `
(async () => {
const { createPersistentCacheStore } = await import('./cache.js');
const { SqliteCacheStore } = await import('./sqlite-cache-store.js');
const store = await createPersistentCacheStore('dummy-sqlite-env');
if (!(store instanceof SqliteCacheStore)) {
console.error('Expected SqliteCacheStore, got:', store.constructor.name);
process.exit(1);
}
})().catch(err => {
console.error(err);
process.exit(2);
});
`;
const { execFileSync } = require('node:child_process');
execFileSync(process.execPath, ['--input-type=module', '-e', code], {
cwd: __dirname,
env: {
...process.env,
NG_BUILD_CACHE_STORE: 'sqlite',
},
});
});

it('should force LMDB when NG_BUILD_CACHE_STORE=lmdb', () => {
const code = `
(async () => {
const { createPersistentCacheStore } = await import('./cache.js');
const { LmdbCacheStore } = await import('./lmdb-cache-store.js');
const store = await createPersistentCacheStore('dummy-lmdb-env');
if (!(store instanceof LmdbCacheStore)) {
console.error('Expected LmdbCacheStore, got:', store.constructor.name);
process.exit(1);
}
})().catch(err => {
console.error(err);
process.exit(2);
});
`;
const { execFileSync } = require('node:child_process');
try {
execFileSync(process.execPath, ['--input-type=module', '-e', code], {
cwd: __dirname,
env: {
...process.env,
NG_BUILD_CACHE_STORE: 'lmdb',
},
});
} catch (e) {
if (e && typeof e === 'object' && 'message' in e) {
const error = e as { message: string; stderr?: Buffer };
const output = error.stderr?.toString() || error.message;
if (!output.includes('Unable to initialize JavaScript cache storage')) {
throw e;
}
} else {
throw e;
}
}
});
});
});
16 changes: 16 additions & 0 deletions packages/angular/build/src/utils/environment-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,19 @@ export const bazelEsbuildPluginPath =
bazelBinDirectory && bazelExecRoot
? process.env['NG_INTERNAL_ESBUILD_PLUGINS_DO_NOT_USE']
: undefined;

/**
* The persistent cache store configuration to use.
* Managed by the `NG_BUILD_CACHE_STORE` environment variable.
* - 'lmdb': Forces the use of LMDB.
* - 'sqlite': Forces the use of SQLite.
* - undefined / 'auto' / other: Automatically uses LMDB and falls back to SQLite.
*/
export const persistentCacheStoreSetting = (() => {
const env = process.env['NG_BUILD_CACHE_STORE']?.trim().toLowerCase();
if (env === 'lmdb' || env === 'sqlite') {
return env;
}

return undefined;
})();
Loading