diff --git a/CHANGELOG.md b/CHANGELOG.md index ff657dcba865..242c793852b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,8 @@ - `[jest-fake-timers]` `getTimerCount` will not include cancelled immediates ([#8764](https://github.com/facebook/jest/pull/8764)) - `[jest-leak-detector]` [**BREAKING**] Use `weak-napi` instead of `weak` package ([#8686](https://github.com/facebook/jest/pull/8686)) - `[jest-mock]` Fix for mockReturnValue overriding mockImplementationOnce ([#8398](https://github.com/facebook/jest/pull/8398)) -- `[jest-reporters]` Make node-notifer an optional dependency ([#8918](https://github.com/facebook/jest/pull/8918)) +- `[jest-reporters]` Make node-notifier an optional dependency ([#8918](https://github.com/facebook/jest/pull/8918)) +- `[jest-resolve]`: Set MODULE_NOT_FOUND as error code when module is not resolved from paths ([#8487](https://github.com/facebook/jest/pull/8487)) - `[jest-snapshot]` Remove only the added newlines in multiline snapshots ([#8859](https://github.com/facebook/jest/pull/8859)) - `[jest-snapshot]` Distinguish empty string from external snapshot not written ([#8880](https://github.com/facebook/jest/pull/8880)) - `[jest-snapshot]` [**BREAKING**] Distinguish empty string from internal snapshot not written ([#8898](https://github.com/facebook/jest/pull/8898)) diff --git a/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap b/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap index f1297995f3ed..ca8e5b11d543 100644 --- a/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap +++ b/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap @@ -30,6 +30,6 @@ FAIL __tests__/index.js 12 | module.exports = () => 'test'; 13 | - at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:483:17) + at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:487:17) at Object.require (index.js:10:1) `; diff --git a/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap b/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap index 59a8c40fb8ef..6daf83e4f1e2 100644 --- a/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap +++ b/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap @@ -32,6 +32,6 @@ FAIL __tests__/test.js | ^ 9 | - at Resolver.resolveModule (../../packages/jest-resolve/build/index.js:272:17) + at Resolver.resolveModule (../../packages/jest-resolve/build/index.js:276:11) at Object.require (index.js:8:18) `; diff --git a/e2e/resolve-with-paths/__tests__/resolveWithPaths.test.js b/e2e/resolve-with-paths/__tests__/resolveWithPaths.test.js index 86b3867022a0..43a4dd97402e 100644 --- a/e2e/resolve-with-paths/__tests__/resolveWithPaths.test.js +++ b/e2e/resolve-with-paths/__tests__/resolveWithPaths.test.js @@ -35,3 +35,9 @@ test('throws an error if the module cannot be found from given paths', () => { "Cannot resolve module './mod.js' from paths ['..'] from " ); }); + +test('throws module not found error if the module cannot be found from given paths', () => { + expect(() => require.resolve('./mod.js', {paths: ['..']})).toThrow( + expect.objectContaining({code: 'MODULE_NOT_FOUND'}) + ); +}); diff --git a/e2e/resolve/__tests__/resolve.test.js b/e2e/resolve/__tests__/resolve.test.js index cf3dab907b12..56f99f7ee945 100644 --- a/e2e/resolve/__tests__/resolve.test.js +++ b/e2e/resolve/__tests__/resolve.test.js @@ -98,3 +98,12 @@ test('should require resolve haste mocks correctly', () => { expect(require('Test6').key).toBe('mock'); }); + +test('should throw module not found error if the module cannot be found', () => { + expect(() => require('Test7')).toThrow( + expect.objectContaining({ + code: 'MODULE_NOT_FOUND', + message: "Cannot find module 'Test7' from 'resolve.test.js'", + }) + ); +}); diff --git a/packages/jest-resolve/src/ModuleNotFoundError.ts b/packages/jest-resolve/src/ModuleNotFoundError.ts new file mode 100644 index 000000000000..6ddfd2c9f372 --- /dev/null +++ b/packages/jest-resolve/src/ModuleNotFoundError.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export default class ModuleNotFoundError extends Error { + code = 'MODULE_NOT_FOUND'; +} diff --git a/packages/jest-resolve/src/defaultResolver.ts b/packages/jest-resolve/src/defaultResolver.ts index 44f66d6e8ee6..3c88694e5982 100644 --- a/packages/jest-resolve/src/defaultResolver.ts +++ b/packages/jest-resolve/src/defaultResolver.ts @@ -12,6 +12,7 @@ import pnpResolver from 'jest-pnp-resolver'; import {Config} from '@jest/types'; import isBuiltinModule from './isBuiltinModule'; import nodeModulesPaths from './nodeModulesPaths'; +import ModuleNotFoundError from './ModuleNotFoundError'; type ResolverOptions = { basedir: Config.Path; @@ -84,11 +85,9 @@ function resolveSync( return target; } - const err: Error & {code?: string} = new Error( + throw new ModuleNotFoundError( "Cannot find module '" + target + "' from '" + basedir + "'", ); - err.code = 'MODULE_NOT_FOUND'; - throw err; /* * contextual helper functions diff --git a/packages/jest-resolve/src/index.ts b/packages/jest-resolve/src/index.ts index 621fc348874f..5d536bff8889 100644 --- a/packages/jest-resolve/src/index.ts +++ b/packages/jest-resolve/src/index.ts @@ -14,6 +14,7 @@ import nodeModulesPaths from './nodeModulesPaths'; import isBuiltinModule from './isBuiltinModule'; import defaultResolver, {clearDefaultResolverCache} from './defaultResolver'; import {ResolverConfig} from './types'; +import ModuleNotFoundError from './ModuleNotFoundError'; type FindNodeModuleConfig = { basedir: Config.Path; @@ -79,6 +80,8 @@ class Resolver { this._modulePathCache = new Map(); } + static ModuleNotFoundError = ModuleNotFoundError; + static clearDefaultResolverCache() { clearDefaultResolverCache(); } @@ -209,11 +212,10 @@ class Resolver { // produces an error based on the dirname but we have the actual current // module name available. const relativePath = path.relative(dirname, from); - const err: Error & {code?: string} = new Error( + + throw new ModuleNotFoundError( `Cannot find module '${moduleName}' from '${relativePath || '.'}'`, ); - err.code = 'MODULE_NOT_FOUND'; - throw err; } isCoreModule(moduleName: string): boolean { diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 18921b7825bd..bbffd575bbd5 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -647,7 +647,8 @@ class Runtime { return module; } } - throw new Error( + + throw new Resolver.ModuleNotFoundError( `Cannot resolve module '${moduleName}' from paths ['${paths.join( "', '", )}'] from ${from}`,