-
Notifications
You must be signed in to change notification settings - Fork 455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TS imports with .js extension break Jest-resolve #1057
Comments
I facing the same issue :( Maybe we must to create a custom resolver for jest as workaround to solve this issue. |
I set up a custom resolver and just published it to npm: |
@kulshekhar this has been closed for awhile but the issue still happen in ts-jest Since handling ".js" extensions in import statement is standard in TypeScript (and will become increasingly needed as Node.js moves towards ES modules), shouldn't ts-jest resolve this correctly without the need for @dpogue custom resolver? |
Which error do you get, TypeScript type checking or Jest runtime errors? I have modified a bit the e2e test https://github.com/ahnpnl/ts-jest/blob/test-test/e2e/__cases__/allow-js/bar.spec.ts and CI still passes https://github.com/ahnpnl/ts-jest/runs/2155197218?check_suite_focus=true (Run tests with coverage) |
A jest-resolve error: FAIL test/index.spec.js
● Test suite failed to run
Cannot find module './types.js' from 'src/index.ts'
Require stack:
src/index.ts
test/index.spec.js
> 1 | import { MyType } from "./types.js";
| ^
2 |
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:306:11)
at Object.<anonymous> (src/index.ts:1:1) importing |
This is Jest runtime error, not
When transforming |
Thanks for the pointers!
Using on "jest-ts-webcompat-resolver", it rewrites |
Won't work for TSX files, but changing a bit the code to also tries resolving path replacing function getResolver() {
try {
return require('jest-resolve/build/defaultResolver').default;
} catch (_) {
return require('jest-resolve/build/default_resolver').default;
}
}
const JAVASCRIPT_EXTENSION = /\.js$/i;
function resolverTSAndTSX(path, options) {
const resolver = options.defaultResolver || getResolver();
try {
return resolver(path, options);
} catch (error) {
if (!JAVASCRIPT_EXTENSION.test(path)) throw error;
try {
return resolver(path.replace(JAVASCRIPT_EXTENSION, '.ts'), options);
} catch (_) {
return resolver(path.replace(JAVASCRIPT_EXTENSION, '.tsx'), options);
}
}
}
module.exports = resolverTSAndTSX; I'll made a PR tomorrow, but this should be included in ts-jest for sure. EDIT: I've create a package to resolve imports same way TS does with import paths that has ".js" extension. |
custom resolver doesn't belong to The issue is mainly caused by when using It is important to distinguish between runtime error vs type checking error. Runtime errors are from Jest and type checking errors are from |
TS resolves module imports when using ".js" extension, ts-jest should do the same in jest. Or at least a explanation on how to do it, since its treated by TS, but not by ts-jest when using TS and jest. |
The output of
This is a correct As I said above, |
In |
Actually, the preset means "A Jest configuration". This preset includes a transformer, which compiles What
|
This involved adding a jest-ts-webcompat-resolver, because jest's resolver doesn't like importing ".js" files that are actually ".ts" files unlike tsc, which is fine with it. See kulshekhar/ts-jest#1057
In order to support ESM, files need to be imported and exported with file extenstions. While Jest seems to support ESM via hack config, we are using ts-jest, so in order to make file extensions to work, we need a moduleNameMapper configuration that allows to remove the file extension, so jest can resolve properly. Related links: kulshekhar/ts-jest#2475 kulshekhar/ts-jest#1057 https://dev.to/antongolub/ts-and-ts-jest-meet-type-module-5chc
In order to support ESM, files need to be imported and exported with file extenstions. While Jest seems to support ESM via hack config, we are using ts-jest, so in order to make file extensions to work, we need a moduleNameMapper configuration that allows to remove the file extension, so jest can resolve properly. Related links: kulshekhar/ts-jest#2475 kulshekhar/ts-jest#1057 https://dev.to/antongolub/ts-and-ts-jest-meet-type-module-5chc
In order to support ESM, files need to be imported and exported with file extenstions. While Jest seems to support ESM via hack config, we are using ts-jest, so in order to make file extensions to work, we need a moduleNameMapper configuration that allows to remove the file extension, so jest can resolve properly. Related links: kulshekhar/ts-jest#2475 kulshekhar/ts-jest#1057 https://dev.to/antongolub/ts-and-ts-jest-meet-type-module-5chc
In order to support ESM, files need to be imported and exported with file extenstions. While Jest seems to support ESM via hack config, we are using ts-jest, so in order to make file extensions to work, we need a moduleNameMapper configuration that allows to remove the file extension, so jest can resolve properly. Related links: kulshekhar/ts-jest#2475 kulshekhar/ts-jest#1057 https://dev.to/antongolub/ts-and-ts-jest-meet-type-module-5chc
I got things working with /** @type {import('@jest/types').Config.ProjectConfig} */
const config = {
transform: {
"\\.[jt]sx?$": "ts-jest",
},
"globals": {
"ts-jest": {
"useESM": true
}
},
moduleNameMapper: {
"(.+)\\.js": "$1"
},
extensionsToTreatAsEsm: [".ts"],
};
export default config; |
I noticed our unit tests were failing because Jest couldn't resolve files with a .js extension. This is a known issue documented here [1] and this PR updates our jest config to fix it. 1: kulshekhar/ts-jest#1057 TEST=auto Ran unit tests.
* Fix Jest config I noticed our unit tests were failing because Jest couldn't resolve files with a .js extension. This is a known issue documented here [1] and this PR updates our jest config to fix it. 1: kulshekhar/ts-jest#1057 TEST=auto Ran unit tests. * npm run release && npm run fmt * Update packages/yext-sites-scripts/package.json Co-authored-by: Justin Mancusi <11779614+mancusi@users.noreply.github.com> Co-authored-by: Justin Mancusi <11779614+mancusi@users.noreply.github.com>
When importing a cross-referenced file, a line like this is generated: import { MyMessage } from '../myother/myother' .. assuming there's a proto at ../myother/myother.proto But if we add the suffix '.pb.ts' to the generated files: import { MyMessage } from '../myother/myother.pb' Is not recognized as a TypeScript import by tsc because of the .pb suffix. To fix this, we can just add .js, and the TypeScript compiler recognizes that we actually mean the .ts file: import { MyMessage } from '../myother/myother.pb.js' Fixes stephenh#601 Fix the resolution in ts-jest with the jest-ts-webcompat-resolver: See: kulshekhar/ts-jest#1057 (comment) Signed-off-by: Christian Stewart <christian@paral.in>
When importing a cross-referenced file, a line like this is generated: import { MyMessage } from '../myother/myother' .. assuming there's a proto at ../myother/myother.proto But if we add the suffix '.pb.ts' to the generated files: import { MyMessage } from '../myother/myother.pb' Is not recognized as a TypeScript import by tsc because of the .pb suffix. To fix this, we can just add .js, and the TypeScript compiler recognizes that we actually mean the .ts file: import { MyMessage } from '../myother/myother.pb.js' Fixes stephenh#601 Fix the resolution in ts-jest with the jest-ts-webcompat-resolver: See: kulshekhar/ts-jest#1057 (comment) Signed-off-by: Christian Stewart <christian@paral.in>
When importing a cross-referenced file, a line like this is generated: import { MyMessage } from '../myother/myother' .. assuming there's a proto at ../myother/myother.proto But if we add the suffix '.pb.ts' to the generated files: import { MyMessage } from '../myother/myother.pb' Is not recognized as a TypeScript import by tsc because of the .pb suffix. To fix this, we can just add .js, and the TypeScript compiler recognizes that we actually mean the .ts file: import { MyMessage } from '../myother/myother.pb.js' Fixes stephenh#601 Fix the resolution in ts-jest with the jest-ts-webcompat-resolver: See: kulshekhar/ts-jest#1057 (comment) Signed-off-by: Christian Stewart <christian@paral.in>
This comment started me on the right path, but for my project, the solution is simpler: make sure the In
|
I tweaked the above version to allow
|
@justrhysism you must double the backslashes:
|
@ahnpnl In my very humble opinion, if someone gives a Jest plugin for people to write
|
`"type": "module"` in `package.json` necessitates including the `.js` file extension in file `import` statements. Details in [TypeScript docs: `type` in `package.json`](https://www.typescriptlang.org/docs/handbook/esm-node.html#type-in-packagejson-and-new-extensions). Then, to fix `npm test`, I added the `moduleNameMapper` from kulshekhar/ts-jest#1057 (comment) (fixing the quotes).
the "cannot find module *.js from *.spec.ts" is a known Typescript + Node + Jest combination issue. Refer the following for more info: https://stackoverflow.com/questions/73735202/typescript-jest-imports-with-js-extension-cause-error-cannot-find-module kulshekhar/ts-jest#1057 (comment)
the "cannot find module *.js from *.spec.ts" is a known Typescript + Node + Jest combination issue. Refer the following for more info: https://stackoverflow.com/questions/73735202/typescript-jest-imports-with-js-extension-cause-error-cannot-find-module kulshekhar/ts-jest#1057 (comment)
As part of looking into #887 I ran into a ton of difficulty getting `ts-jest` to work with ESM, with one of the main issues being related to importing `./utils.js` style files. This seems to be an issue with `ts-jest` (or at least the interplay between `ts-jest` and Jest) and from what I could tell in the issues and code, this isn't solved yet. The solution to the underlying issue was "fixed" by suggesting the use of a custom resolver, which is not part of the main `ts-jest` package (see kulshekhar/ts-jest#1057). While checking types in the test code is useful, it's not that important since the actual code is type checked separately (both with the linter and the compilation steps), and so instead of trying to fix `ts-jest` and use the custom resolver, I opt for using `@swc/jest` which instead removes the types entirely.
As part of looking into #887 I ran into a ton of difficulty getting `ts-jest` to work with ESM, with one of the main issues being related to importing `./utils.js` style files. This seems to be an issue with TypeScript + Jest combination when using ESM, and the `ts-jest` preset hasn't "fixed" this yet (by doing something like the `moduleNameMapper` approach mentioned in [comments like this] (kulshekhar/ts-jest#1057 (comment)). Has there not been any PR from someone? In any case, it's a bit frustrating that there wasn't a mention of this in the troubleshooting docs as the issue above was pretty well trafficked and commented on, and while there was a PR, it was closed and there was no follow up. What's worse is that this issue has been known for at least 4 years. There really should have been a troubleshooting section added here even without a community contributed PR, and so I don't have faith that either an additon to the preset or a mention in the troubleshooting docs will happen anytime soon, at least before I want to get Stylelint 16 in main. While checking types in the test code is useful, it's not that important since the actual code is type checked separately (both with the linter and the compilation steps), and so instead of trying to fix `ts-jest` and use the custom resolver, I opt for using `@swc/jest` which instead removes the types entirely when compiling TS to JS. It has the added benefit of being simpler, being only used in the `transform` config rather than as a preset. If at some point type checking the tests becomes important the lint:types task can be updated to check test code too.
As part of looking into #887 I ran into a ton of difficulty getting `ts-jest` to work with ESM, with one of the main issues being related to importing `./utils.js` style files. This seems to be an issue with the combination of TypeScript + Jest when using ESM, and the `ts-jest` preset hasn't "fixed" this yet (by doing something like the `moduleNameMapper` approach mentioned in [comments like this] (kulshekhar/ts-jest#1057 (comment)). Has there not been any PR from someone? In any case, it's a bit frustrating that there wasn't a mention of this in the troubleshooting docs as the issue above was pretty well trafficked and commented on, and while there was a PR, it was closed and there was no follow up. What's worse is that this issue has been known for at least 4 years. There really should have been a troubleshooting section added here even without a community contributed PR, and so I don't have faith that either an additon to the preset or a mention in the troubleshooting docs will happen anytime soon, at least before I want to get Stylelint 16 in main. While checking types in the test code is useful, it's not that important since the actual code is type checked separately (both with the linter and the compilation steps), and so instead of trying to fix `ts-jest` and use the custom resolver, I opt for using `@swc/jest` which instead removes the types entirely when compiling TS to JS. It has the added benefit of being simpler, being only used in the `transform` config rather than as a preset. If at some point type checking the tests becomes important the lint:types task can be updated to check test code too.
As part of looking into #887 I ran into a ton of difficulty getting `ts-jest` to work with ESM, with one of the main issues being related to importing `./utils.js` style files. This seems to be an issue with the combination of TypeScript + Jest when using ESM, and the `ts-jest` preset hasn't "fixed" this yet (by doing something like the `moduleNameMapper` approach mentioned in [comments like this](kulshekhar/ts-jest#1057 (comment)). Has there not been any PR from someone? In any case, it's a bit frustrating that there wasn't a mention of this in the troubleshooting docs as the issue above was pretty well trafficked and commented on, and while there was a PR, it was closed and there was no follow up. What's worse is that this issue has been known for at least 4 years. There really should have been a troubleshooting section added here even without a community contributed PR, and so I don't have faith that either an additon to the preset or a mention in the troubleshooting docs will happen anytime soon, at least before I want to get Stylelint 16 in main. While checking types in the test code is useful, it's not that important since the actual code is type checked separately (both with the linter and the compilation steps), and so instead of trying to fix `ts-jest` and use the custom resolver, I opt for using `@swc/jest` which instead removes the types entirely when compiling TS to JS. It has the added benefit of being simpler, being only used in the `transform` config rather than as a preset. If at some point type checking the tests becomes important the lint:types task can be updated to check test code too.
As part of looking into #887 I ran into a ton of difficulty getting `ts-jest` to work with ESM, with one of the main issues being related to importing `./utils.js` style files. This seems to be an issue with the combination of TypeScript + Jest when using ESM, and the `ts-jest` preset hasn't "fixed" this yet (by doing something like the `moduleNameMapper` approach mentioned in [comments like this](kulshekhar/ts-jest#1057 (comment)). Has there not been any PR from someone? In any case, it's a bit frustrating that there wasn't a mention of this in the troubleshooting docs as the issue above was pretty well trafficked and commented on, and while there was a PR, it was closed and there was no follow up. What's worse is that this issue has been known for at least 4 years. There really should have been a troubleshooting section added here even without a community contributed PR, and so I don't have faith that either an additon to the preset or a mention in the troubleshooting docs will happen anytime soon, at least before I want to get Stylelint 16 in main. While checking types in the test code is useful, it's not that important since the actual code is type checked separately (both with the linter and the compilation steps), and since `@swc/jest` is simpler and hopefully doesn't have the above frustration factor, I've decided to migrate from `ts-jest` to `@swc/jest`. If at some point type checking the tests becomes important the lint:types task can be updated to check test code too.
Since the global ts-jest config is considered as deprecated. I adjust the good tips by this way
|
The below works for me in my Node.js backend project. The rule applies to relative imports starting with a period (.) or double periods (..) "moduleNameMapper": {
"@src/(.*)": "<rootDir>/src/$1",
"^(\\./.+|\\../.+).js$": "$1"
} OR "moduleNameMapper": {
"@src/(.*)": "<rootDir>/src/$1",
"^(..?/.+).js?$": "$1"
}, |
Found the solution and a long discussion about it here: kulshekhar/ts-jest#1057 TLDR: The Jest resolver needs a little extra information/tweak to the config so that it can correctly handle the .js imports. Specifically this comment provided the solution which I made here: kulshekhar/ts-jest#1057 (comment) Fixes hyperledger-cacti#3254 Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
Found the solution and a long discussion about it here: kulshekhar/ts-jest#1057 TLDR: The Jest resolver needs a little extra information/tweak to the config so that it can correctly handle the .js imports. Specifically this comment provided the solution which I made here: kulshekhar/ts-jest#1057 (comment) Fixes hyperledger-cacti#3254 Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
Found the solution and a long discussion about it here: kulshekhar/ts-jest#1057 TLDR: The Jest resolver needs a little extra information/tweak to the config so that it can correctly handle the .js imports. Specifically this comment provided the solution which I made here: kulshekhar/ts-jest#1057 (comment) Fixes hyperledger-cacti#3254 Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
Found the solution and a long discussion about it here: kulshekhar/ts-jest#1057 TLDR: The Jest resolver needs a little extra information/tweak to the config so that it can correctly handle the .js imports. Specifically this comment provided the solution which I made here: kulshekhar/ts-jest#1057 (comment) Fixes #3254 Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
Found the solution and a long discussion about it here: kulshekhar/ts-jest#1057 TLDR: The Jest resolver needs a little extra information/tweak to the config so that it can correctly handle the .js imports. Specifically this comment provided the solution which I made here: kulshekhar/ts-jest#1057 (comment) Fixes hyperledger-cacti#3254 Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
* Fix Error ***ERR_MODULE_NOT_FOUND***: Cannot find module '/app/dst/utils/currency' imported from /app/dst/messages.js * Let jest use the ts files when importing js files See: kulshekhar/ts-jest#1057 * Fix more extension-less imports
Issue :
TypeScript files using web-compatible ES6 imports cause Jest to throw an error about not being able to find the module. This error comes from
jest-resolve/build/index.js:229
and happens regardless of the module type specified in ts-jest (commonjs, amd, ES6, etc.)Expected behavior :
TypeScript supports adding a
.js
extension to import statements for web-compatibility (since imports require a full path, including the extension).I would expect ts-jest to allow TypeScript to handle this and convert it to commonjs before it gets passed to jest.
Minimal repo :
The text was updated successfully, but these errors were encountered: