Skip to content

Commit

Permalink
feat(resolver): support node: prefix when loading core modules
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Aug 13, 2021
1 parent 315784d commit 9caa82f
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 22 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

### Features

- `[jest-resolver]` Support `node:` prefix when importing Node core modules ([#11331](https://github.com/facebook/jest/pull/11331))

### Fixes

### Chore & Maintenance
Expand Down Expand Up @@ -100,6 +102,7 @@
- `[@jest/fake-timers]` Update to `@sinonjs/fake-timers` to v7 ([#11198](https://github.com/facebook/jest/pull/11198))
- `[jest-haste-map]` Handle injected scm clocks ([#10966](https://github.com/facebook/jest/pull/10966))
- `[jest-haste-map]` Add `enableSymlinks` configuration option to follow symlinks for test files ([#9351](https://github.com/facebook/jest/pull/9351))
- `[jest-reporters]` Add static filepath property to all reporters ([#11015](https://github.com/facebook/jest/pull/11015))
- `[jest-repl, jest-runner]` [**BREAKING**] Run transforms over environment ([#8751](https://github.com/facebook/jest/pull/8751))
- `[jest-repl]` Add support for `testEnvironment` written in ESM ([#11232](https://github.com/facebook/jest/pull/11232))
- `[jest-runner]` [**BREAKING**] set exit code to 1 if test logs after teardown ([#10728](https://github.com/facebook/jest/pull/10728))
Expand All @@ -109,7 +112,6 @@
- `[jest-runner]` Add support for `testRunner` written in ESM ([#11232](https://github.com/facebook/jest/pull/11232))
- `[jest-runtime]` Detect reexports from CJS as named exports in ESM ([#10988](https://github.com/facebook/jest/pull/10988))
- `[jest-runtime]` Support for async code transformations ([#11191](https://github.com/facebook/jest/pull/11191) & [#11220](https://github.com/facebook/jest/pull/11220))
- `[jest-reporters]` Add static filepath property to all reporters ([#11015](https://github.com/facebook/jest/pull/11015))
- `[jest-snapshot]` [**BREAKING**] Make prettier optional for inline snapshots - fall back to string replacement ([#7792](https://github.com/facebook/jest/pull/7792) & [#11192](https://github.com/facebook/jest/pull/11192))
- `[jest-snapshot]` [**BREAKING**] Run transforms over `snapshotResolver` ([#8751](https://github.com/facebook/jest/pull/8829))
- `[jest-transform]` Pass config options defined in Jest's config to transformer's `process` and `getCacheKey` functions ([#10926](https://github.com/facebook/jest/pull/10926))
Expand Down
4 changes: 2 additions & 2 deletions e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap
Expand Up @@ -41,7 +41,7 @@ FAIL __tests__/index.js
12 | module.exports = () => 'test';
13 |
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:558:17)
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:561:17)
at Object.require (index.js:10:1)
`;

Expand Down Expand Up @@ -70,6 +70,6 @@ FAIL __tests__/index.js
12 | module.exports = () => 'test';
13 |
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:558:17)
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:561:17)
at Object.require (index.js:10:1)
`;
Expand Up @@ -37,6 +37,6 @@ FAIL __tests__/test.js
| ^
9 |
at Resolver.resolveModule (../../packages/jest-resolve/build/resolver.js:311:11)
at Resolver.resolveModule (../../packages/jest-resolve/build/resolver.js:313:11)
at Object.require (index.js:8:18)
`;
12 changes: 2 additions & 10 deletions packages/jest-resolve/src/isBuiltinModule.ts
Expand Up @@ -7,19 +7,11 @@

import module = require('module');

// "private" api
declare const process: NodeJS.Process & {
binding(type: string): Record<string, unknown>;
};

// TODO: remove when we drop support for node v10 - it is included from node v12
const EXPERIMENTAL_MODULES = ['worker_threads'];

const BUILTIN_MODULES = new Set(
module.builtinModules
? module.builtinModules.concat(EXPERIMENTAL_MODULES)
: Object.keys(process.binding('natives'))
.filter((module: string) => !/^internal\//.test(module))
.concat(EXPERIMENTAL_MODULES),
module.builtinModules.concat(EXPERIMENTAL_MODULES),
);

export default function isBuiltinModule(module: string): boolean {
Expand Down
10 changes: 5 additions & 5 deletions packages/jest-resolve/src/resolver.ts
Expand Up @@ -135,7 +135,7 @@ export default class Resolver {
moduleName: string,
options?: ResolveModuleConfig,
): Config.Path | null {
const paths = (options && options.paths) || this._options.modulePaths;
const paths = options?.paths || this._options.modulePaths;
const moduleDirectory = this._options.moduleDirectories;
const key = dirname + path.delimiter + moduleName;
const defaultPlatform = this._options.defaultPlatform;
Expand Down Expand Up @@ -253,7 +253,9 @@ export default class Resolver {
isCoreModule(moduleName: string): boolean {
return (
this._options.hasCoreModules &&
isBuiltinModule(moduleName) &&
(isBuiltinModule(moduleName) ||
(moduleName.startsWith('node:') &&
isBuiltinModule(moduleName.slice('node:'.length)))) &&
!this._isAliasModule(moduleName)
);
}
Expand Down Expand Up @@ -313,10 +315,8 @@ export default class Resolver {
getModuleID(
virtualMocks: Map<string, boolean>,
from: Config.Path,
_moduleName?: string,
moduleName = '',
): string {
const moduleName = _moduleName || '';

const key = from + path.delimiter + moduleName;
const cachedModuleID = this._moduleIDCache.get(key);
if (cachedModuleID) {
Expand Down
11 changes: 11 additions & 0 deletions packages/jest-runtime/src/__tests__/runtime_require_module.test.js
Expand Up @@ -188,6 +188,17 @@ describe('Runtime requireModule', () => {
}).not.toThrow();
});

it('finds node core built-in modules with node:prefix', async () => {
const runtime = await createRuntime(__filename);

expect(runtime.requireModule(runtime.__mockRootPath, 'fs')).toBe(
runtime.requireModule(runtime.__mockRootPath, 'node:fs'),
);
expect(runtime.requireModule(runtime.__mockRootPath, 'module')).toBe(
runtime.requireModule(runtime.__mockRootPath, 'node:module'),
);
});

it('finds and loads JSON files without file extension', async () => {
const runtime = await createRuntime(__filename);
const exports = runtime.requireModule(runtime.__mockRootPath, './JSONFile');
Expand Down
10 changes: 7 additions & 3 deletions packages/jest-runtime/src/index.ts
Expand Up @@ -1332,15 +1332,19 @@ export default class Runtime {
}

private _requireCoreModule(moduleName: string) {
if (moduleName === 'process') {
const moduleWithoutNodePrefix = moduleName.startsWith('node:')
? moduleName.slice('node:'.length)
: moduleName;

if (moduleWithoutNodePrefix === 'process') {
return this._environment.global.process;
}

if (moduleName === 'module') {
if (moduleWithoutNodePrefix === 'module') {
return this._getMockedNativeModule();
}

return require(moduleName);
return require(moduleWithoutNodePrefix);
}

private _importCoreModule(moduleName: string, context: VMContext) {
Expand Down

0 comments on commit 9caa82f

Please sign in to comment.