From f8d4c998f8f9999a571dfbd68c5094f5aefaa2ca Mon Sep 17 00:00:00 2001 From: ahnpnl Date: Fri, 28 Feb 2025 08:45:56 +0100 Subject: [PATCH] refactor: remove global setup script with `ngcc` BREAKING CHANGE Running 'ngcc' is not required for Angular 16+ projects --- global-setup.js | 1 - global-setup.mjs | 3 - scripts/test-examples.js | 22 +++---- src/config/global-setup.spec.ts | 36 ----------- src/config/global-setup.ts | 9 --- src/utils/ngcc-jest-processor.ts | 95 ------------------------------ website/docs/guides/angular-ivy.md | 70 ---------------------- website/sidebars.json | 1 - 8 files changed, 7 insertions(+), 230 deletions(-) delete mode 100644 global-setup.js delete mode 100644 global-setup.mjs delete mode 100644 src/config/global-setup.spec.ts delete mode 100644 src/config/global-setup.ts delete mode 100644 src/utils/ngcc-jest-processor.ts delete mode 100644 website/docs/guides/angular-ivy.md diff --git a/global-setup.js b/global-setup.js deleted file mode 100644 index aa32b5bc70..0000000000 --- a/global-setup.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./build/config/global-setup').globalSetup; diff --git a/global-setup.mjs b/global-setup.mjs deleted file mode 100644 index 6564ceaa39..0000000000 --- a/global-setup.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import { globalSetup } from './build/config/global-setup.js'; - -export default globalSetup; diff --git a/scripts/test-examples.js b/scripts/test-examples.js index ba369a5acb..75ffce751e 100755 --- a/scripts/test-examples.js +++ b/scripts/test-examples.js @@ -34,21 +34,13 @@ const executeTest = (projectPath) => { logger.log('installing bundled version of jest-preset-angular'); logger.log(); - [ - 'build', - 'presets', - 'global-setup.js', - 'global-setup.mjs', - 'jest-preset.js', - 'package.json', - 'setup-jest.js', - 'setup-jest.mjs', - 'setup-env', - ].forEach((asset) => { - const assetToReplace = join(projectPath, 'node_modules', 'jest-preset-angular', asset); - const assetToCopy = join(rootDir, asset); - copySync(assetToCopy, assetToReplace, {}); - }); + ['build', 'presets', 'jest-preset.js', 'package.json', 'setup-jest.js', 'setup-jest.mjs', 'setup-env'].forEach( + (asset) => { + const assetToReplace = join(projectPath, 'node_modules', 'jest-preset-angular', asset); + const assetToCopy = join(rootDir, asset); + copySync(assetToCopy, assetToReplace, {}); + }, + ); // then we can run the tests const cmdLine = ['yarn', 'test']; diff --git a/src/config/global-setup.spec.ts b/src/config/global-setup.spec.ts deleted file mode 100644 index 92f66ecea6..0000000000 --- a/src/config/global-setup.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { globalSetup } from './global-setup'; - -jest.mock('../utils/ngcc-jest-processor', () => { - return { - runNgccJestProcessor() { - console.log('Mock ngcc jest processor'); - }, - }; -}); - -describe('global-setup', () => { - test('should skip ngcc-jest-processor with `skipNgcc: true` option in `ngJest` config', async () => { - console.log = jest.fn(); - globalThis.ngJest = { - skipNgcc: true, - }; - - await globalSetup(); - - expect(console.log).not.toHaveBeenCalled(); - }); - - test.each([false, undefined])( - 'should not skip ngcc-jest-processor with `skipNgcc: %s` option in `ngJest` config', - async (skipNgcc) => { - console.log = jest.fn(); - globalThis.ngJest = { - skipNgcc, - }; - - await globalSetup(); - - expect(console.log).toHaveBeenCalled(); - }, - ); -}); diff --git a/src/config/global-setup.ts b/src/config/global-setup.ts deleted file mode 100644 index 539e1f3ec5..0000000000 --- a/src/config/global-setup.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { runNgccJestProcessor } from '../utils/ngcc-jest-processor'; - -export const globalSetup = async () => { - const ngJestConfig = globalThis.ngJest; - const tsconfig = ngJestConfig?.tsconfig; - if (!ngJestConfig?.skipNgcc) { - runNgccJestProcessor(tsconfig); - } -}; diff --git a/src/utils/ngcc-jest-processor.ts b/src/utils/ngcc-jest-processor.ts deleted file mode 100644 index 7bf30bf737..0000000000 --- a/src/utils/ngcc-jest-processor.ts +++ /dev/null @@ -1,95 +0,0 @@ -/** - * 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 path from 'path'; - -const ANGULAR_COMPILER_CLI_PKG_NAME = '@angular/compiler-cli'; -let ngccPath = ''; - -try { - ngccPath = require.resolve('@angular/compiler-cli/ngcc/main-ngcc.js'); -} catch { - try { - const compilerCliNgccPath = require.resolve('@angular/compiler-cli/ngcc'); - const compilerCliNgccFolder = compilerCliNgccPath.substring(0, compilerCliNgccPath.lastIndexOf(path.sep)); - ngccPath = path.resolve(compilerCliNgccFolder, 'main-ngcc.js'); - } catch { - // No ngcc in NG16 - } -} -function findNodeModulesDirectory(): string { - return ngccPath.substring(0, ngccPath.indexOf(ANGULAR_COMPILER_CLI_PKG_NAME.replace('/', path.sep))); -} - -function findAngularCompilerCliVersion(): string { - const packagePath = require.resolve(ANGULAR_COMPILER_CLI_PKG_NAME); - const substringLength = - packagePath.indexOf(ANGULAR_COMPILER_CLI_PKG_NAME.replace('/', path.sep)) + - ANGULAR_COMPILER_CLI_PKG_NAME.length; - const ngCompilerCliFolder = packagePath.substring(0, substringLength); - const ngCompilerCliPackageJson = `${ngCompilerCliFolder}/package.json`; - // eslint-disable-next-line @typescript-eslint/no-require-imports - const { version } = require(ngCompilerCliPackageJson); - - return version; -} - -const nodeModuleDirPath = findNodeModulesDirectory(); - -export const runNgccJestProcessor = (tsconfigPath: string | undefined): void => { - const ngCompilerCliVersion = findAngularCompilerCliVersion(); - const [ngMajorVersion] = ngCompilerCliVersion.split('.'); - if (parseInt(ngMajorVersion, 10) >= 16) { - console.warn(` - Running 'ngcc' is not required for Angular 16+ projects. This 'ngcc-jest-processor' script will be removed in the next major version of 'jest-preset-angular'. - Tip: To avoid this message you can remove 'jest-preset-angular/global-setup' from your jest config - `); - - return; - } - - if (ngccPath && 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, ngccBaseArgs, { - stdio: ['inherit', process.stderr, process.stderr], - }); - if (status !== 0) { - const errorMessage: string = error?.message ?? ''; - - throw new Error(`${errorMessage} NGCC failed ${errorMessage ? ', see above' : ''}.`); - } - - return; - } - - console.warn( - `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`, - ); -}; diff --git a/website/docs/guides/angular-ivy.md b/website/docs/guides/angular-ivy.md deleted file mode 100644 index 39bb7c17d6..0000000000 --- a/website/docs/guides/angular-ivy.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -id: angular-ivy -title: Angular Ivy ---- - -:::warning DEPRECATED - -This guide is now **DEPRECATED** and will be removed in the next major release together with the below APIs. - -::: - -Starting from **v9.0.0+**, `jest-preset-angular` is fully compatible with Angular Ivy. To make sure that Jest uses the -Angular Ivy, you must run `ngcc` before running tests. `ngcc` will transform all Angular-format packages to be compatible -with Ivy compiler. - -`jest-preset-angular` also provides a Jest global setup file to help you to run `ngcc` with Jest. Add to the following section: - -- to your root Jest config - -```ts title="jest.config.ts" tab={"label": "TypeScript CJS"} -import type { Config } from 'jest'; - -export default { - //... - globalSetup: 'jest-preset-angular/global-setup', -} satisfies Config; -``` - -```ts title="jest.config.mts" tab={"label": "TypeScript ESM"} -import type { Config } from 'jest'; - -export default { - //... - globalSetup: 'jest-preset-angular/global-setup', -} satisfies Config; -``` - -## Control ngcc processing - -Since **v12.0.0**, `jest-preset-angular` provide a possibility to skip `ngcc` via `globalThis` by doing the following - -```ts title="jest.config.ts" tab={"label": "TypeScript CJS"} -import type { Config } from 'jest'; - -globalThis.ngJest = { - skipNgcc: true, - tsconfig: 'tsconfig.spec.json', // this is the project root tsconfig -}; - -const jestConfig: Config = { - //... - globalSetup: 'jest-preset-angular/global-setup', -}; - -export default jestConfig; -``` - -```ts title="jest.config.mts" tab={"label": "TypeScript ESM"} -import type { Config } from 'jest'; - -globalThis.ngJest = { - skipNgcc: true, - tsconfig: 'tsconfig.spec.json', // this is the project root tsconfig -}; - -export default { - //... - globalSetup: 'jest-preset-angular/global-setup', -} satisfies Config; -``` diff --git a/website/sidebars.json b/website/sidebars.json index b209195559..46665d3479 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -12,7 +12,6 @@ "getting-started/testbed-environment" ], "Guides": [ - "guides/angular-ivy", "guides/angular-13+", "guides/esm-support", "guides/jsdom-environment",