From 93e483c0a5f59027b2356c189133d123a2360513 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 27 Sep 2020 15:15:43 +0300 Subject: [PATCH 1/9] refactor(resolve): replace read-pkg-up with escalade Ref https://packagephobia.com/result?p=read-pkg-up https://packagephobia.com/result?p=escalade Read-pkg-up package is quite big and have a lot of dependencies. It also handles cases not necessary for jest. Beautiful JSON parsing errors are not relevant and can be replaced with builtin JSON.parse. --- packages/jest-resolve/package.json | 2 +- packages/jest-resolve/src/shouldLoadAsEsm.ts | 20 +++++++++++++++----- yarn.lock | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/jest-resolve/package.json b/packages/jest-resolve/package.json index 75ff392890fe..9d0532636d78 100644 --- a/packages/jest-resolve/package.json +++ b/packages/jest-resolve/package.json @@ -12,10 +12,10 @@ "dependencies": { "@jest/types": "^26.3.0", "chalk": "^4.0.0", + "escalade": "^3.1.0", "graceful-fs": "^4.2.4", "jest-pnp-resolver": "^1.2.2", "jest-util": "^26.3.0", - "read-pkg-up": "^7.0.1", "resolve": "^1.17.0", "slash": "^3.0.0" }, diff --git a/packages/jest-resolve/src/shouldLoadAsEsm.ts b/packages/jest-resolve/src/shouldLoadAsEsm.ts index cab7b850eae6..c9d61f029b0b 100644 --- a/packages/jest-resolve/src/shouldLoadAsEsm.ts +++ b/packages/jest-resolve/src/shouldLoadAsEsm.ts @@ -8,8 +8,8 @@ import {dirname, extname} from 'path'; // @ts-expect-error: experimental, not added to the types import {SyntheticModule} from 'vm'; +import escalade from 'escalade/sync'; import type {Config} from '@jest/types'; -import readPkgUp = require('read-pkg-up'); const runtimeSupportsVmModules = typeof SyntheticModule === 'function'; @@ -68,11 +68,21 @@ function shouldLoadAsEsm(path: Config.Path): boolean { function cachedPkgCheck(cwd: Config.Path): boolean { // TODO: can we cache lookups somehow? - const pkg = readPkgUp.sync({cwd, normalize: false}); - - if (!pkg) { + const pkgContent = escalade(cwd, (_dir, names) => { + if (names.includes('package.json')) { + // will be resolved into absolute + return 'package.json'; + } + return false; + }); + if (!pkgContent) { return false; } - return pkg.packageJson.type === 'module'; + try { + const pkg = JSON.parse(pkgContent); + return pkg.type === 'module'; + } catch (e) { + return false; + } } diff --git a/yarn.lock b/yarn.lock index d39891853c33..59702da2e1aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7743,7 +7743,7 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.0.2": +"escalade@npm:^3.0.2, escalade@npm:^3.1.0": version: 3.1.0 resolution: "escalade@npm:3.1.0" checksum: 437c5b2619a412c0b075fb33e590e3516f187f7da8b20035685e08f346e27842722e5740a3398535d7d590ae4fb70068374ed59190d4eb4f9bb06d052e2fc92f @@ -11758,11 +11758,11 @@ fsevents@^1.2.7: "@types/graceful-fs": ^4.1.3 "@types/resolve": ^1.17.0 chalk: ^4.0.0 + escalade: ^3.1.0 graceful-fs: ^4.2.4 jest-haste-map: ^26.3.0 jest-pnp-resolver: ^1.2.2 jest-util: ^26.3.0 - read-pkg-up: ^7.0.1 resolve: ^1.17.0 slash: ^3.0.0 languageName: unknown From d94d4e51b345c8f47bfc36618dc26023d2c7b2ce Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 27 Sep 2020 17:21:21 +0300 Subject: [PATCH 2/9] Test es modules only since 13.7 --- e2e/__tests__/nativeEsm.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/__tests__/nativeEsm.test.ts b/e2e/__tests__/nativeEsm.test.ts index e8addfb934f3..3344b9c8abf6 100644 --- a/e2e/__tests__/nativeEsm.test.ts +++ b/e2e/__tests__/nativeEsm.test.ts @@ -21,7 +21,7 @@ test('test config is without transform', () => { }); // The versions vm.Module was introduced -onNodeVersions('^12.16.0 || >=13.2.0', () => { +onNodeVersions('^12.16.0 || >=13.7.0', () => { test('runs test with native ESM', () => { const {exitCode, stderr, stdout} = runJest(DIR, [], { nodeOptions: '--experimental-vm-modules', From 1c30fcee6b3b0069aa416d7499245dc071d7172b Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 27 Sep 2020 18:38:09 +0300 Subject: [PATCH 3/9] Update snapshot --- e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap index 953aa9a25bfa..eb5d4ee7e03c 100644 --- a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap +++ b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`on node ^12.16.0 || >=13.2.0 runs test with native ESM 1`] = ` +exports[`on node ^12.16.0 || >=13.7.0 runs test with native ESM 1`] = ` Test Suites: 1 passed, 1 total Tests: 12 passed, 12 total Snapshots: 0 total From 6e5c5c57450b309f745ed717b08414dcd070991f Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Tue, 29 Sep 2020 20:56:05 +0300 Subject: [PATCH 4/9] Fix escalade usage --- packages/jest-resolve/src/shouldLoadAsEsm.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/jest-resolve/src/shouldLoadAsEsm.ts b/packages/jest-resolve/src/shouldLoadAsEsm.ts index c9d61f029b0b..b0e9715aece7 100644 --- a/packages/jest-resolve/src/shouldLoadAsEsm.ts +++ b/packages/jest-resolve/src/shouldLoadAsEsm.ts @@ -6,6 +6,7 @@ */ import {dirname, extname} from 'path'; +import {readFileSync} from 'fs'; // @ts-expect-error: experimental, not added to the types import {SyntheticModule} from 'vm'; import escalade from 'escalade/sync'; @@ -68,19 +69,19 @@ function shouldLoadAsEsm(path: Config.Path): boolean { function cachedPkgCheck(cwd: Config.Path): boolean { // TODO: can we cache lookups somehow? - const pkgContent = escalade(cwd, (_dir, names) => { + const pkgPath = escalade(cwd, (_dir, names) => { if (names.includes('package.json')) { // will be resolved into absolute return 'package.json'; } return false; }); - if (!pkgContent) { + if (!pkgPath) { return false; } try { - const pkg = JSON.parse(pkgContent); + const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')); return pkg.type === 'module'; } catch (e) { return false; From f60d005edc407b54ccbafe92c49b673f0a190d2b Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 1 Oct 2020 14:04:59 +0300 Subject: [PATCH 5/9] Address comments --- packages/jest-resolve/src/shouldLoadAsEsm.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/jest-resolve/src/shouldLoadAsEsm.ts b/packages/jest-resolve/src/shouldLoadAsEsm.ts index b0e9715aece7..9b05b022bb92 100644 --- a/packages/jest-resolve/src/shouldLoadAsEsm.ts +++ b/packages/jest-resolve/src/shouldLoadAsEsm.ts @@ -6,9 +6,9 @@ */ import {dirname, extname} from 'path'; -import {readFileSync} from 'fs'; // @ts-expect-error: experimental, not added to the types import {SyntheticModule} from 'vm'; +import {readFileSync} from 'graceful-fs'; import escalade from 'escalade/sync'; import type {Config} from '@jest/types'; @@ -16,6 +16,7 @@ const runtimeSupportsVmModules = typeof SyntheticModule === 'function'; const cachedFileLookups = new Map(); const cachedDirLookups = new Map(); +const cachedChecks = new Map(); export function clearCachedLookups(): void { cachedFileLookups.clear(); @@ -80,10 +81,18 @@ function cachedPkgCheck(cwd: Config.Path): boolean { return false; } + let hasModuleField = cachedChecks.get(pkgPath); + if (hasModuleField != null) { + return hasModuleField; + } + try { const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')); - return pkg.type === 'module'; + hasModuleField = pkg.type === 'module'; } catch (e) { - return false; + hasModuleField = false; } + + cachedChecks.set(pkgPath, hasModuleField); + return hasModuleField; } From 0fed3c5171597f48030436ab2ec5b8f6d4616a5e Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 1 Oct 2020 14:06:53 +0300 Subject: [PATCH 6/9] Add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99689b1d4169..95b3d0ec82d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ ### Chore & Maintenance +- `[jest-resolve]` Replace read-pkg-up with escalade package ([10558](https://github.com/facebook/jest/pull/10558)) + ### Performance ## 26.4.2 From a7073d7bfa93ebe79ee7f996e6c257ad048d4575 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 1 Oct 2020 14:32:14 +0300 Subject: [PATCH 7/9] Add clear and use optional catch --- packages/jest-resolve/src/shouldLoadAsEsm.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/jest-resolve/src/shouldLoadAsEsm.ts b/packages/jest-resolve/src/shouldLoadAsEsm.ts index 9b05b022bb92..1ae3014ace83 100644 --- a/packages/jest-resolve/src/shouldLoadAsEsm.ts +++ b/packages/jest-resolve/src/shouldLoadAsEsm.ts @@ -21,6 +21,7 @@ const cachedChecks = new Map(); export function clearCachedLookups(): void { cachedFileLookups.clear(); cachedDirLookups.clear(); + cachedChecks.clear(); } export default function cachedShouldLoadAsEsm(path: Config.Path): boolean { @@ -89,7 +90,7 @@ function cachedPkgCheck(cwd: Config.Path): boolean { try { const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')); hasModuleField = pkg.type === 'module'; - } catch (e) { + } catch { hasModuleField = false; } From c12fe4a9f4e55d24e0968072fb6fa811c639a3e1 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 1 Oct 2020 14:39:57 +0300 Subject: [PATCH 8/9] Update test comment --- e2e/__tests__/nativeEsm.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/__tests__/nativeEsm.test.ts b/e2e/__tests__/nativeEsm.test.ts index 3344b9c8abf6..49a8427ab0c9 100644 --- a/e2e/__tests__/nativeEsm.test.ts +++ b/e2e/__tests__/nativeEsm.test.ts @@ -20,7 +20,7 @@ test('test config is without transform', () => { expect(configs[0].transform).toEqual([]); }); -// The versions vm.Module was introduced +// The versions where vm.Module exists and commonjs with "exports" is not broken onNodeVersions('^12.16.0 || >=13.7.0', () => { test('runs test with native ESM', () => { const {exitCode, stderr, stdout} = runJest(DIR, [], { From 92411f99a91d2f7b6a3ec2a5d3883f3707720e52 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 1 Oct 2020 14:40:22 +0300 Subject: [PATCH 9/9] Delete comment about cache --- packages/jest-resolve/src/shouldLoadAsEsm.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/jest-resolve/src/shouldLoadAsEsm.ts b/packages/jest-resolve/src/shouldLoadAsEsm.ts index 1ae3014ace83..654f4e75c8d7 100644 --- a/packages/jest-resolve/src/shouldLoadAsEsm.ts +++ b/packages/jest-resolve/src/shouldLoadAsEsm.ts @@ -70,7 +70,6 @@ function shouldLoadAsEsm(path: Config.Path): boolean { } function cachedPkgCheck(cwd: Config.Path): boolean { - // TODO: can we cache lookups somehow? const pkgPath = escalade(cwd, (_dir, names) => { if (names.includes('package.json')) { // will be resolved into absolute