Skip to content

Commit

Permalink
feat: allow running ngcc with specific tsconfig path
Browse files Browse the repository at this point in the history
  • Loading branch information
anh.pham committed Apr 25, 2022
1 parent 7950b5c commit 09c1aa9
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 24 deletions.
9 changes: 6 additions & 3 deletions src/config/global-setup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Config } from '@jest/types';
import type { TsJestGlobalOptions } from 'ts-jest/dist/types';

import { runNgccJestProcessor } from '../utils/ngcc-jest-processor';

Expand All @@ -7,11 +8,13 @@ interface NgJestProjectConfig extends Omit<Config.ProjectConfig, 'globals'> {
ngJest?: {
skipNgcc: boolean;
};
tsJest?: TsJestGlobalOptions;
};
}

export = async (_globalConfig: Config.GlobalConfig, projectConfig: NgJestProjectConfig) => {
if (!projectConfig.globals.ngJest?.skipNgcc) {
runNgccJestProcessor();
export = async (_globalConfig: Config.GlobalConfig, { globals }: NgJestProjectConfig) => {
if (!globals.ngJest?.skipNgcc) {
const tsconfig = globals.tsJest?.tsconfig;
runNgccJestProcessor(typeof tsconfig === 'string' ? tsconfig : undefined);
}
};
31 changes: 31 additions & 0 deletions src/utils/__snapshots__/ngcc-jest-processor.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ngcc-jest-processor should execute @angular/compiler-cli ngcc with tsconfig path foo 1`] = `
Array [
"/node_modules/@angular/compiler-cli/bundles/ngcc/main-ngcc.js",
"--source",
"/node_modules/",
"--properties",
"es2015",
"main",
"--first-only",
"false",
"--async",
"--tsconfig",
"foo",
]
`;

exports[`ngcc-jest-processor should execute @angular/compiler-cli ngcc with tsconfig path undefined 1`] = `
Array [
"/node_modules/@angular/compiler-cli/bundles/ngcc/main-ngcc.js",
"--source",
"/node_modules/",
"--properties",
"es2015",
"main",
"--first-only",
"false",
"--async",
]
`;
20 changes: 20 additions & 0 deletions src/utils/ngcc-jest-processor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import childProcess from 'child_process';

import { runNgccJestProcessor } from './ngcc-jest-processor';

describe('ngcc-jest-processor', () => {
test.each(['foo', undefined])('should execute @angular/compiler-cli ngcc with tsconfig path %s', (tsconfigPath) => {
const mockedSpawnSync = (childProcess.spawnSync = jest.fn().mockReturnValueOnce({
status: 0,
}));

runNgccJestProcessor(tsconfigPath);

expect(childProcess.spawnSync).toHaveBeenCalled();
expect(mockedSpawnSync.mock.calls[0][0]).toBe(process.execPath);
const ngccArgs = (mockedSpawnSync.mock.calls[0][1] as string[]).map((arg) => arg.replace(process.cwd(), ''));
expect(ngccArgs).toMatchSnapshot();

jest.restoreAllMocks();
});
});
43 changes: 22 additions & 21 deletions src/utils/ngcc-jest-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,35 @@ function findNodeModulesDirectory(): string {

const nodeModuleDirPath = findNodeModulesDirectory();

export const runNgccJestProcessor = (): void => {
export const runNgccJestProcessor = (tsconfigPath: string | undefined): void => {
if (nodeModuleDirPath) {
process.stdout.write('\nngcc-jest-processor: running ngcc\n');

const ngccBaseArgs = [
ngccPath,
'--source' /** basePath */,
nodeModuleDirPath,
'--properties' /** propertiesToConsider */,
/**
* There are various properties: fesm2015, fesm5, es2015, esm2015, esm5, main, module, browser to choose from.
* Normally, Jest requires `umd`. If running Jest in ESM mode, Jest will require both `umd` + `esm2015`.
*/
...['es2015', 'main'],
'--first-only' /** compileAllFormats */,
'false', // make sure that `ngcc` runs on subfolders as well
'--async',
];
if (tsconfigPath) {
ngccBaseArgs.push(...['--tsconfig', tsconfigPath]);
}
// We spawn instead of using the API because:
// - NGCC Async uses clustering which is problematic when used via the API which means
// that we cannot setup multiple cluster masters with different options.
// - We will not be able to have concurrent builds otherwise Ex: App-Shell,
// as NGCC will create a lock file for both builds and it will cause builds to fails.
const { status, error } = spawnSync(
process.execPath,
[
ngccPath,
'--source' /** basePath */,
nodeModuleDirPath,
'--properties' /** propertiesToConsider */,
/**
* There are various properties: fesm2015, fesm5, es2015, esm2015, esm5, main, module, browser to choose from.
* Normally, Jest requires `umd`. If running Jest in ESM mode, Jest will require both `umd` + `esm2015`.
*/
...['es2015', 'main'],
'--first-only' /** compileAllFormats */,
'false', // make sure that `ngcc` runs on subfolders as well
'--async',
],
{
stdio: ['inherit', process.stderr, process.stderr],
},
);
const { status, error } = spawnSync(process.execPath, ngccBaseArgs, {
stdio: ['inherit', process.stderr, process.stderr],
});
if (status !== 0) {
const errorMessage: string = error?.message ?? '';

Expand Down

0 comments on commit 09c1aa9

Please sign in to comment.