Skip to content

Commit

Permalink
perf(compiler): reuse cacheFS from jest to reduce file system readi…
Browse files Browse the repository at this point in the history
…ng (#679)
  • Loading branch information
ahnpnl committed Dec 18, 2020
1 parent 0df3ce1 commit f5d9d4b
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 24 deletions.
6 changes: 4 additions & 2 deletions src/__tests__/index.spec.ts
Expand Up @@ -10,6 +10,7 @@ describe('NgJestTransformer', () => {
() => {
const obj1 = {
config: { cwd: process.cwd(), extensionsToTreatAsEsm: [], globals: {}, testMatch: [], testRegex: [] },
cacheFS: new Map(),
};
const obj2 = { ...obj1, config: { ...obj1.config, globals: {} } };
// eslint-disable-next-line
Expand All @@ -24,6 +25,7 @@ describe('NgJestTransformer', () => {
test('should return the same config set for same values with jest config objects', () => {
const obj1 = {
config: { cwd: process.cwd(), extensionsToTreatAsEsm: [], globals: {}, testMatch: [], testRegex: [] },
cacheFS: new Map(),
};
const obj2 = { ...obj1 };
// eslint-disable-next-line
Expand Down Expand Up @@ -84,7 +86,7 @@ describe('NgJestTransformer', () => {
const input = {
fileContent: 'const foo = 1',
// eslint-disable-next-line
options: { config: { ...jestCfg } as any, instrument: false, rootDir: '/foo' },
options: { config: { ...jestCfg } as any, instrument: false, rootDir: '/foo', cacheFS: new Map(), },
};
// eslint-disable-next-line
const ngJestTransformer = require('../');
Expand Down Expand Up @@ -121,7 +123,7 @@ describe('NgJestTransformer', () => {
};
const input = {
// eslint-disable-next-line
options: { config: { ...jestCfg } as any, instrument: false, rootDir: '/foo' },
options: { config: { ...jestCfg } as any, instrument: false, rootDir: '/foo', cacheFS: new Map(), },
};
// eslint-disable-next-line
const ngJestTransformer = require('../');
Expand Down
16 changes: 8 additions & 8 deletions src/__tests__/ng-jest-compiler.spec.ts
Expand Up @@ -45,7 +45,7 @@ describe('NgJestCompiler', () => {
// Isolated modules true doesn't have downlevel ctor so this snapshot test should produce different input than with Program
test('should return result', () => {
const fileName = join(__dirname, '__mocks__', 'foo.service.ts');
const compiler = new NgJestCompiler(ngJestConfig);
const compiler = new NgJestCompiler(ngJestConfig, new Map());

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
compiler.getCompiledOutput(fileName, readFileSync(fileName, 'utf-8'))!;
Expand All @@ -60,7 +60,7 @@ describe('NgJestCompiler', () => {
...ngJestConfig.parsedTsConfig,
rootNames: [fileName],
};
const compiler = new NgJestCompiler(ngJestConfig);
const compiler = new NgJestCompiler(ngJestConfig, new Map());

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
compiler.getCompiledOutput(fileName, readFileSync(fileName, 'utf-8'))!;
Expand All @@ -79,7 +79,7 @@ describe('NgJestCompiler', () => {
...ngJestConfig.parsedTsConfig,
rootNames: [],
};
const compiler = new NgJestCompiler(ngJestConfig);
const compiler = new NgJestCompiler(ngJestConfig, new Map());

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const emittedResult = compiler.getCompiledOutput(fileName, readFileSync(fileName, 'utf-8'))!;
Expand All @@ -94,7 +94,7 @@ describe('NgJestCompiler', () => {
...ngJestConfig.parsedTsConfig,
rootNames: [fileName],
};
const compiler = new NgJestCompiler(ngJestConfig);
const compiler = new NgJestCompiler(ngJestConfig, new Map());

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const emittedResult = compiler.getCompiledOutput(fileName, readFileSync(fileName, 'utf-8'))!;
Expand All @@ -109,7 +109,7 @@ describe('NgJestCompiler', () => {
...ngJestConfig.parsedTsConfig,
rootNames: [],
};
const compiler = new NgJestCompiler(ngJestConfig);
const compiler = new NgJestCompiler(ngJestConfig, new Map());

expect(() =>
compiler.getCompiledOutput('foo.ts', readFileSync(fileName, 'utf-8')),
Expand All @@ -122,7 +122,7 @@ describe('NgJestCompiler', () => {
...ngJestConfig.parsedTsConfig,
rootNames: [fileName],
};
const compiler = new NgJestCompiler(ngJestConfig);
const compiler = new NgJestCompiler(ngJestConfig, new Map());

expect(() =>
compiler.getCompiledOutput(fileName, readFileSync(fileName, 'utf-8')),
Expand All @@ -136,7 +136,7 @@ describe('NgJestCompiler', () => {
rootNames: [fileName],
};
ngJestConfig.shouldReportDiagnostics = jest.fn().mockReturnValueOnce(false);
const compiler = new NgJestCompiler(ngJestConfig);
const compiler = new NgJestCompiler(ngJestConfig, new Map());

expect(() => compiler.getCompiledOutput(fileName, readFileSync(fileName, 'utf-8'))).not.toThrowError();
});
Expand All @@ -148,7 +148,7 @@ describe('NgJestCompiler', () => {
...ngJestConfig.parsedTsConfig,
rootNames: [fileName],
};
const compiler = new NgJestCompiler(ngJestConfig);
const compiler = new NgJestCompiler(ngJestConfig, new Map());

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const emittedResult = compiler.getCompiledOutput(fileName, readFileSync(fileName, 'utf-8'))!;
Expand Down
24 changes: 13 additions & 11 deletions src/compiler/compiler-host.ts
Expand Up @@ -9,12 +9,11 @@ import type { CompilerOptions } from '@angular/compiler-cli';

export class NgJestCompilerHost implements ts.CompilerHost {
private readonly _sourceFileCache: Map<string, ts.SourceFile> = new Map<string, ts.SourceFile>();
private readonly _memoryHost: Map<string, string | undefined> = new Map<string, string | undefined>();
private readonly _emittedResult: [string, string] = ['', ''];
private readonly _ts: TTypeScript;
private readonly _moduleResolutionCache: ts.ModuleResolutionCache;

constructor(private logger: Logger, private ngJestCfg: NgJestConfig) {
constructor(readonly logger: Logger, readonly ngJestCfg: NgJestConfig, readonly jestCacheFS: Map<string, string>) {
this._ts = this.ngJestCfg.compilerModule;
this._moduleResolutionCache = this._ts.createModuleResolutionCache(this.ngJestCfg.cwd, (x) => x);
}
Expand All @@ -24,10 +23,10 @@ export class NgJestCompilerHost implements ts.CompilerHost {
}

updateMemoryHost(fileName: string, fileContent: string): void {
const previousContents = this._memoryHost.get(fileName);
const previousContents = this.jestCacheFS.get(fileName);
const contentsChanged = previousContents !== fileContent;
if (contentsChanged) {
this._memoryHost.set(fileName, fileContent);
this.jestCacheFS.set(fileName, fileContent);
}
}

Expand Down Expand Up @@ -92,15 +91,18 @@ export class NgJestCompilerHost implements ts.CompilerHost {

readFile(fileName: string): string | undefined {
const normalizedFileName = normalize(fileName);
let fileContent = this._memoryHost.get(normalizedFileName);
if (!fileContent) {
this.logger.debug(
{ fileName: normalizedFileName },
'readFile: file does not exist in memory cache, read file with file system',
);
let fileContent = this.jestCacheFS.get(normalizedFileName);

this.logger.debug(
{ fileName: normalizedFileName },
'readFile: file does not exist in memory cache, read file with file system',
);

if (!fileContent) {
fileContent = this._ts.sys.readFile(normalizedFileName) ?? undefined;
this._memoryHost.set(normalizedFileName, fileContent);
if (fileContent) {
this.jestCacheFS.set(normalizedFileName, fileContent);
}
}

return fileContent;
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/ng-jest-compiler.ts
Expand Up @@ -18,7 +18,7 @@ export class NgJestCompiler implements CompilerInstance {
private readonly _logger: Logger;
private readonly _ts: TTypeScript;

constructor(readonly ngJestConfig: NgJestConfig) {
constructor(readonly ngJestConfig: NgJestConfig, readonly jestCacheFS: Map<string, string>) {
this._logger = this.ngJestConfig.logger;
this._ts = this.ngJestConfig.compilerModule;
this._setupOptions(this.ngJestConfig);
Expand Down Expand Up @@ -117,7 +117,7 @@ export class NgJestCompiler implements CompilerInstance {
'_setupOptions: creating Compiler Host using @angular/compiler-cli createCompilerHost',
);

this._tsHost = new NgJestCompilerHost(this._logger, this.ngJestConfig);
this._tsHost = new NgJestCompilerHost(this._logger, this.ngJestConfig, this.jestCacheFS);
this._compilerHost = createCompilerHost({
options: this._compilerOptions,
tsHost: this._tsHost,
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Expand Up @@ -74,7 +74,7 @@ class NgJestTransformer extends TsJestTransformer {
this._logger.info('no matching config-set found, creating a new one');

ngJestConfig = new NgJestConfig(jestConfig);
this._compiler = new NgJestCompiler(ngJestConfig);
this._compiler = new NgJestCompiler(ngJestConfig, transformOptions.cacheFS);
this._transformCfgStr = new JsonableValue({
...jestConfig,
...ngJestConfig.parsedTsConfig,
Expand Down

0 comments on commit f5d9d4b

Please sign in to comment.