jest: SyntaxError: Cannot use import statement outside a module, with TypeScript and ES Modules
š Bug Report
Filing a separate issue at @SimenBās suggestion.
After following the steps to get native ESM support, Iām running into the following error in a project that transpiles TypeScript files using @babel/preset-typescript
:
/home/dandv/jets/lib.test.ts:1
import { foo } from './lib';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime._execModule (node_modules/jest-runtime/build/index.js:1074:58)
To Reproduce
git clone https://github.com/dandv/jest-typescript-es-modules.git
cd jest-typescript-es-modules
npm install
npm test
Expected behavior
Test passes.
Link to repl or repo (highly encouraged)
https://github.com/dandv/jest-typescript-es-modules
envinfo
System:
OS: Linux 5.3 Ubuntu 18.04.4 LTS (Bionic Beaver)
CPU: (8) x64 Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz
Binaries:
Node: 13.13.0 - /usr/bin/node
npm: 6.14.4 - ~/.local/bin/npm
npmPackages:
jest: ^25.4.0 => 25.4.0
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 9
- Comments: 45 (34 by maintainers)
I had the same problem. Iāve fixed that by including js files in ts-node:
"transform": { "^.+\\.(ts|tsx|js|jsx)?$": "ts-jest" }
Hi, I stumbled across this issue and thought Iād say hi. Iām the maintainer of CoffeeScript and Iāve been dealing with this same issue. In my case, there are plenty of legacy
.coffee
files out there that userequire
/CommonJS, including the CoffeeScript codebase itself. My plan is to treat.coffee
as equivalent to.js
, as in, ābehave however a.js
file would at this pathāāso if itās in a"type": "module"
package scope, itās ESM. I think thatās the safest approach; even if you think all TypeScript youāll ever encounter usesimport
/export
, I wouldnāt be surprised if there are some folks out there who have been mixingimport
andrequire
statements occasionally, since presumably they currently work.Thanks for chiming in! I think that makes sense for us as well - itās what we already do for CJS - we require you to transform whatever you import to CJS before Jest will load it. And if youāve opted into ESM for
.js
files I think itās a pretty safe assumption that you want the same behavior for yourts
(or.coffee
,.vue
) files. Happy to hear people in the modules WG are thinking along the same lines šIāve published
jest@next
now, please give it a whirl! šYeah, thatās suggested syntax, itās not implemented yet. Will be included in Jest 27 which will come sometime before Christmas (hopefully earlier, but I donāt wanna make any promises Iām not able to keep)
Yeah, Iām currently working (on and off) on adding native ESM support, see #9430. This issue is a small, but important part of that work š
cc @lmiller1990
@SimenB Is it safe to use this approach for
ts-jest
asts-jest
only needs to transformts/tsx
tomjs/cjs
depending on tsconfigtarget
?Maybe only the case when transforming files from
node_modules
, it is necessary to checktype: module
inpackage.json
ātransplantationā, nice autocorrect š but with Babel, TS is a completely different thing than CJS, if you use plugin-typescript but not plugin-transform-modules-commonjs, types get stripped but it remains ESM
yeyy tests run now š
Only real drawback is that itās a breaking change. Should be fine tho, letās go for it. PR welcome, if not Iāll get to this in a few weeks š
I like that suggestion! We already support passing config to transformers, like so
I guess we could have a third argument which is āconfig for jestā? Then stick
moduleFormat
in there.We could also go for your suggestion of accepting an object - simple enough to normalize the user config into that as well.
This one is very simple indeed and easy to do.
Top level configuration option is also fine by me. Currently,
ts-jest
has internal logic to detect whether users want to usebabel-jest
.I think we can also have
??
Yup. Itās quite simple to fix, but I donāt think we want to special case
.ts
,.tsx
or.jsx
for that matter. What about people using.coffee
,.vue
etc.?Right now the logic is
.mjs
is always ESM.cjs
is always CJS.js
is ESM if closestpackage.json
has atype: 'module'
field, otherwise CJSWhat Iām thinking makes sense is to make that last one behave like
js
, i.e. infer from thetype
field. But it might be better to add an option that overrides this check and says ātreat ts and tsx as ESMā?Take my transpile config https://github.com/askirmas/askirmas.github.io/blob/8d1a0f2601c2683597edaa473f3b9ca9068abd72/jest.schema.json#L756-L773