|
| 1 | +/** |
| 2 | + * Mainly copied from https://github.com/angular/angular-cli/blob/master/packages/ngtools/webpack/src/ngcc_processor.ts |
| 3 | + * and adjusted to work with Jest |
| 4 | + */ |
| 5 | +import { spawnSync } from 'child_process'; |
| 6 | +import { existsSync } from 'fs'; |
| 7 | +import { dirname, join } from 'path'; |
| 8 | + |
| 9 | +const IGNORE_ARGS = ['--clearCache', '--help', '--init', '--listTests', '--showConfig']; |
| 10 | +const canRunNgcc = !process.argv.find((arg) => IGNORE_ARGS.includes(arg)); |
| 11 | +function findNodeModulesDirectory(startPoint: string): string { |
| 12 | + let current = startPoint; |
| 13 | + while (dirname(current) !== current) { |
| 14 | + const nodePath = join(current, 'node_modules'); |
| 15 | + if (existsSync(nodePath)) { |
| 16 | + return nodePath; |
| 17 | + } |
| 18 | + |
| 19 | + current = dirname(current); |
| 20 | + } |
| 21 | + |
| 22 | + throw new Error( |
| 23 | + `Cannot locate the 'node_modules' directory. Please make sure you are running jest from root level of your project`, |
| 24 | + ); |
| 25 | +} |
| 26 | + |
| 27 | +if (canRunNgcc) { |
| 28 | + process.stdout.write('ngcc-jest-processor: running ngcc\n'); |
| 29 | + // We spawn instead of using the API because: |
| 30 | + // - NGCC Async uses clustering which is problematic when used via the API which means |
| 31 | + // that we cannot setup multiple cluster masters with different options. |
| 32 | + // - We will not be able to have concurrent builds otherwise Ex: App-Shell, |
| 33 | + // as NGCC will create a lock file for both builds and it will cause builds to fails. |
| 34 | + const { status, error } = spawnSync( |
| 35 | + process.execPath, |
| 36 | + [ |
| 37 | + require.resolve('@angular/compiler-cli/ngcc/main-ngcc.js'), |
| 38 | + '--source' /** basePath */, |
| 39 | + findNodeModulesDirectory(process.cwd()), |
| 40 | + '--properties' /** propertiesToConsider */, |
| 41 | + /** |
| 42 | + * There are various properties: fesm2015, fesm5, es2015, esm2015, esm5, main, module, browser to choose from. |
| 43 | + * Currently Jest requires `commonjs` so we only need to ask `ngcc` to produce `umd` outputs. Later when switching |
| 44 | + * to ESM, we can change to different properties to produce ESM outputs. |
| 45 | + */ |
| 46 | + ...['es2015', 'main'], |
| 47 | + '--first-only' /** compileAllFormats */, |
| 48 | + 'false', // make sure that `ngcc` runs on subfolders as well |
| 49 | + '--async', |
| 50 | + ], |
| 51 | + { |
| 52 | + stdio: ['inherit', process.stderr, process.stderr], |
| 53 | + }, |
| 54 | + ); |
| 55 | + if (status !== 0) { |
| 56 | + const errorMessage: string = error?.message ?? ''; |
| 57 | + |
| 58 | + throw new Error(`${errorMessage} NGCC failed ${errorMessage ? ', see above' : ''}.`); |
| 59 | + } |
| 60 | +} |
0 commit comments