Skip to content

Commit

Permalink
fix(utils): allow skipping ngcc-jest-processor via some Jest args (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ahnpnl authored Sep 21, 2021
1 parent 15f4321 commit 7d3a712
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 37 deletions.
47 changes: 47 additions & 0 deletions src/__tests__/ngcc-jest-processor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import child_process from 'child_process';

describe('ngcc-jest-processor', () => {
test.concurrent.each(['--clearCache', '--help', '--init', '--listTests', '--showConfig'])(
'should not run ngcc when having excluded Jest args',
async (ignoreArg) => {
child_process.spawnSync = jest.fn();
process.argv.push(ignoreArg);

await import('../utils/ngcc-jest-processor');

expect(child_process.spawnSync).not.toHaveBeenCalled();
},
);

test.concurrent('should run ngcc when not having excluded Jest args with successful result', async () => {
const mockedSpawnSync = (child_process.spawnSync = jest.fn().mockReturnValueOnce({
status: 0,
}));
process.argv = [];
process.stdout.write = jest.fn();

await import('../utils/ngcc-jest-processor');

expect(process.stdout.write).toHaveBeenCalledWith('ngcc-jest-processor: running ngcc\n');
expect(mockedSpawnSync).toHaveBeenCalled();
expect(
mockedSpawnSync.mock.calls[0][1].map((callArg: string) =>
callArg.includes('node_modules')
? callArg.substring(callArg.indexOf('node_modules')).replace(/\\/g, '/')
: callArg,
),
).toMatchInlineSnapshot(`
Array [
"node_modules/@angular/compiler-cli/ngcc/main-ngcc.js",
"--source",
"node_modules/",
"--properties",
"es2015",
"main",
"--first-only",
"false",
"--async",
]
`);
});
});
75 changes: 38 additions & 37 deletions src/utils/ngcc-jest-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { sep } from 'path';
const IGNORE_ARGS = ['--clearCache', '--help', '--init', '--listTests', '--showConfig'];
const ANGULAR_COMPILER_CLI_PKG_NAME = `@angular${sep}compiler-cli`;
const nodeModuleDirPath = findNodeModulesDirectory();
const canRunNgcc = !process.argv.find((arg) => IGNORE_ARGS.includes(arg)) && !!nodeModuleDirPath;

function findNodeModulesDirectory(): string {
let nodeModulesPath = '';
Expand All @@ -23,42 +22,44 @@ function findNodeModulesDirectory(): string {
return nodeModulesPath;
}

if (canRunNgcc) {
process.stdout.write('ngcc-jest-processor: running ngcc\n');
// 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,
[
require.resolve('@angular/compiler-cli/ngcc/main-ngcc.js'),
'--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],
},
);
if (status !== 0) {
const errorMessage: string = error?.message ?? '';
if (!process.argv.find((arg) => IGNORE_ARGS.includes(arg))) {
if (nodeModuleDirPath) {
process.stdout.write('ngcc-jest-processor: running ngcc\n');
// 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,
[
require.resolve('@angular/compiler-cli/ngcc/main-ngcc.js'),
'--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],
},
);
if (status !== 0) {
const errorMessage: string = error?.message ?? '';

throw new Error(`${errorMessage} NGCC failed ${errorMessage ? ', see above' : ''}.`);
throw new Error(`${errorMessage} NGCC failed ${errorMessage ? ', see above' : ''}.`);
}
} else {
console.log(
`Warning: Could not locate '@angular/compiler-cli' to run 'ngcc' automatically.` +
`Please make sure you are running 'ngcc-jest-processor.js' from root level of your project.` +
`'ngcc' must be run before running Jest`,
);
}
} else {
console.log(
`Warning: Could not locate '@angular/compiler-cli' to run 'ngcc' automatically.` +
`Please make sure you are running 'ngcc-jest-processor.js' from root level of your project.` +
`'ngcc' must be run before running Jest`,
);
}

0 comments on commit 7d3a712

Please sign in to comment.