ts-jest: TS imports with .js extension break Jest-resolve
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 :
/* user.ts */
export class User {
public name : string;
constructor(name : string) {
this.name = name;
}
}
/* user.spec.ts */
import { User } from './user.js';
describe('User', function() {
});
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 32
- Comments: 22
Commits related to this issue
- Get tests working with new esm import statements. This involved adding a jest-ts-webcompat-resolver, because jest's resolver doesn't like importing ".js" files that are actually ".ts" files unlike ts... — committed to johndaniels/es-interpreter by johndaniels 3 years ago
- import/export with js extension 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 orde... — committed to joselcvarela/directus by joselcvarela 3 years ago
- import/export with js extension 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 orde... — committed to directus/directus by joselcvarela 3 years ago
- import/export with js extension 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 orde... — committed to directus/directus by joselcvarela 3 years ago
- import/export with js extension 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 orde... — committed to joselcvarela/directus by joselcvarela 3 years ago
- Fix tests per https://github.com/kulshekhar/ts-jest/issues/1057#issuecomment-1068342692 — committed to IntelliTect/Coalesce by ascott18 2 years ago
- 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... — committed to yext/pages by jimboHenris 2 years ago
- Fix jest (#65) * 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... — committed to yext/pages by jimboHenris 2 years ago
- fix: add .js suffix to proto cross-reference imports When importing a cross-referenced file, a line like this is generated: import { MyMessage } from '../myother/myother' .. assuming there's a pr... — committed to paralin/ts-proto by paralin 2 years ago
- fix: add .js suffix to proto cross-reference imports When importing a cross-referenced file, a line like this is generated: import { MyMessage } from '../myother/myother' .. assuming there's a pr... — committed to paralin/ts-proto by paralin 2 years ago
- fix: add .js suffix to proto cross-reference imports When importing a cross-referenced file, a line like this is generated: import { MyMessage } from '../myother/myother' .. assuming there's a pr... — committed to paralin/ts-proto by paralin 2 years ago
- fix: add .js suffix to proto cross-reference imports When importing a cross-referenced file, a line like this is generated: import { MyMessage } from '../myother/myother' .. assuming there's a pr... — committed to paralin/ts-proto by paralin 2 years ago
- fix: add .js suffix to proto cross-reference imports (#602) When importing a cross-referenced file, a line like this is generated: import { MyMessage } from '../myother/myother' .. assuming t... — committed to stephenh/ts-proto by paralin 2 years ago
- chore(release): 1.116.1 [skip ci] ## [1.116.1](https://github.com/stephenh/ts-proto/compare/v1.116.0...v1.116.1) (2022-07-02) ### Bug Fixes * add .js suffix to proto cross-reference imports ([#602]... — committed to stephenh/ts-proto by semantic-release-bot 2 years ago
- fix #17 #18 import添加js后缀后,jest报错 参考:https://github.com/kulshekhar/ts-jest/issues/1057 — committed to wtto00/spider-crawler by wtto00 2 years ago
- * [fix] https://github.com/kulshekhar/ts-jest/issues/1057#issuecomment-1068342692 — committed to tatumroaquin/blackjade by tatumroaquin a year ago
- fix: Fix imports during runs and tests (#587) `"type": "module"` in `package.json` necessitates including the `.js` file extension in file `import` statements. Details in [TypeScript docs: `type` i... — committed to smockle/contrast by smockle a year ago
- fix: update moduleNameMapper jest config to recognize .js files the "cannot find module *.js from *.spec.ts" is a known Typescript + Node + Jest combination issue. Refer the following for more info:... — committed to 9akashnp8/expense-tracker by 9akashnp8 9 months ago
- fix: update moduleNameMapper jest config to recognize .js files the "cannot find module *.js from *.spec.ts" is a known Typescript + Node + Jest combination issue. Refer the following for more info:... — committed to 9akashnp8/expense-tracker by 9akashnp8 9 months ago
- Migrate from ts-jest to @swc/jest As part of looking into https://github.com/jo-sm/stylelint_d/pull/887 I ran into a ton of difficulty getting `ts-jest` to work with ESM, with one of the main issues ... — committed to jo-sm/stylelint_d by jo-sm 7 months ago
I got things working with
.jsextensions in typescript imports with the following jest.config.js:I set up a custom resolver and just published it to npm:
jest-ts-webcompat-resolver@justrhysism you must double the backslashes:
Hello,
I want to share my config as well as far as the solution from above didn’t work out for me. I’m using nodejs v18.12.0, jest 29.2.2 and ts-jest 29.0.3, typescript 4.8.4.
I have
"type": "module",in mypackage.json.My
tsconfig.jsonlooks like this:Jest config file
jest.config.cjslooks like this:This comment started me on the right path, but for my project, the solution is simpler: make sure the
moduleNameMapperonly maps the ‘.ts’ files that you refer to as.jsin your imports elsewhere. In my case, those were the./[filename].tsfiles, which are imported as./[filename].jsbut for jest need to be imported as./[filename].In
jest.config.json syntax:@ahnpnl In my very humble opinion, if someone gives a Jest plugin for people to write
.test.tsfiles instead of.test.jsfiles, but it doesn’t work with default functionality of TypeScript, then that’s the plugin author’s problem, not Jest’s..jsextensions for module specifiers are a default out-of-the-box feature of TypeScript.Since the global ts-jest config is considered as deprecated.
I adjust the good tips by this way
I tweaked the above version to allow
../relative imports also:Won’t work for TSX files, but changing a bit the code to also tries resolving path replacing
.jsto.tsxseems to work fine.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. https://github.com/VitorLuizC/ts-jest-resolver
@kulshekhar this has been closed for awhile but the issue still happen in ts-jest
26.5.4.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?
This is Jest runtime error, not
ts-jesttype checking error. There are a few things to check:module.exportsallowJsis true.transformvalue specifyingjsprocessed byts-jestWhen transforming
tstojs, the codefrom "./types.js";becomesrequire(“./types.js”), which is a valid syntax. However, Jest resolver doesn’t understand, probably because missingmodule.exportsA jest-resolve error:
importing
./types.js(./src/types.tsfile exporting some types/enums declarations) from./src/index.ts.ts-jestdoesn’t do anything with Jest module resolution. The job ofts-jestis transformingtstojs. Transforming means compiling. Compiling process doesn’t trigger the codes itself.The output of
import { MyType } from "./types.js";isThis is a correct
jscompiling. However, how thatrequire(\\"./types.js\\")executes depending on Jest.As I said above,
ts-jestis a Jest transformer, please check https://jestjs.io/docs/next/code-transformation to understand more.custom resolver doesn’t belong to
ts-jest.ts-jestis just a Jest transformer to transformtstojsand it doesn’t do anything with the way how Jest resolves a file.ts-jestcan add a section to documentation regarding to this error but natively, it is notts-jestissue so the resolver should stay on its own, not included ints-jestThe issue is mainly caused by when using
jsextension, Node treats it as CommonJS, if you don’t havemodule.exportsit is not a validjsto Node to import.It is important to distinguish between runtime error vs type checking error. Runtime errors are from Jest and type checking errors are from
ts-jest.Related issue at Storybook: https://github.com/storybookjs/storybook/issues/15962 Both Jest and Storybook need to build code from sources, but might encounter index.ts “barrel files” exporting files using .js extension when a librairy is meant to be exposed as ESM.
When not using
ts-jest, this issue could help: https://github.com/swc-project/jest/issues/64#issuecomment-1029753225