Skip to content

Commit

Permalink
feat: add ngcc-jest-processor util script (#853)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahnpnl committed Mar 3, 2021
1 parent 986b127 commit e8c9689
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 3 deletions.
2 changes: 2 additions & 0 deletions e2e/test-app-v10/jest.config.js
@@ -1,3 +1,5 @@
require('jest-preset-angular/ngcc-jest-processor');

/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
moduleNameMapper: {
Expand Down
1 change: 0 additions & 1 deletion e2e/test-app-v10/package.json
Expand Up @@ -7,7 +7,6 @@
"build": "ng build",
"test-cjs-uniso": "jest --clearCache && jest -c=jest-cjs-uniso.config.js",
"test-cjs-iso": "jest --clearCache && jest -c=jest-cjs-iso.config.js",
"postinstall": "ngcc --properties es2015 browser module main",
"lint": "ng lint"
},
"private": true,
Expand Down
2 changes: 2 additions & 0 deletions e2e/test-app-v11/jest.config.js
@@ -1,3 +1,5 @@
require('jest-preset-angular/ngcc-jest-processor');

/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
moduleNameMapper: {
Expand Down
1 change: 0 additions & 1 deletion e2e/test-app-v11/package.json
Expand Up @@ -7,7 +7,6 @@
"build": "ng build",
"test-cjs-uniso": "jest --clearCache && jest -c=jest-cjs-uniso.config.js",
"test-cjs-iso": "jest --clearCache && jest -c=jest-cjs-iso.config.js",
"postinstall": "ngcc --properties es2015 browser module main",
"lint": "ng lint"
},
"private": true,
Expand Down
2 changes: 2 additions & 0 deletions e2e/test-app-v9/jest.config.js
@@ -1,3 +1,5 @@
require('jest-preset-angular/ngcc-jest-processor');

/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
moduleNameMapper: {
Expand Down
1 change: 0 additions & 1 deletion e2e/test-app-v9/package.json
Expand Up @@ -7,7 +7,6 @@
"build": "ng build",
"test-cjs-uniso": "jest --clearCache && jest -c=jest-cjs-uniso.config.js",
"test-cjs-iso": "jest --clearCache && jest -c=jest-cjs-iso.config.js",
"postinstall": "ngcc --properties es2015 browser module main",
"lint": "ng lint"
},
"private": true,
Expand Down
1 change: 1 addition & 0 deletions ngcc-jest-processor.js
@@ -0,0 +1 @@
module.exports = require('./build/utils/ngcc-jest-processor');
1 change: 1 addition & 0 deletions scripts/e2e.js
Expand Up @@ -44,6 +44,7 @@ const executeTest = (projectRealPath) => {

copySync(join(cwd, 'jest-preset.js'), `${presetDir}/jest-preset.js`);
copySync(join(cwd, 'index.js'), `${presetDir}/index.js`);
copySync(join(cwd, 'ngcc-jest-processor.js'), `${presetDir}/ngcc-jest-processor.js`);
copySync(join(cwd, 'package.json'), `${presetDir}/package.json`);
copySync(join(cwd, 'build'), `${presetDir}/build`);

Expand Down
60 changes: 60 additions & 0 deletions src/utils/ngcc-jest-processor.ts
@@ -0,0 +1,60 @@
/**
* Mainly copied from https://github.com/angular/angular-cli/blob/master/packages/ngtools/webpack/src/ngcc_processor.ts
* and adjusted to work with Jest
*/
import { spawnSync } from 'child_process';
import { existsSync } from 'fs';
import { dirname, join } from 'path';

const IGNORE_ARGS = ['--clearCache', '--help', '--init', '--listTests', '--showConfig'];
const canRunNgcc = !process.argv.find((arg) => IGNORE_ARGS.includes(arg));
function findNodeModulesDirectory(startPoint: string): string {
let current = startPoint;
while (dirname(current) !== current) {
const nodePath = join(current, 'node_modules');
if (existsSync(nodePath)) {
return nodePath;
}

current = dirname(current);
}

throw new Error(
`Cannot locate the 'node_modules' directory. Please make sure you are running jest from root level of your project`,
);
}

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 */,
findNodeModulesDirectory(process.cwd()),
'--properties' /** propertiesToConsider */,
/**
* There are various properties: fesm2015, fesm5, es2015, esm2015, esm5, main, module, browser to choose from.
* Currently Jest requires `commonjs` so we only need to ask `ngcc` to produce `umd` outputs. Later when switching
* to ESM, we can change to different properties to produce ESM outputs.
*/
...['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' : ''}.`);
}
}

0 comments on commit e8c9689

Please sign in to comment.