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.gitcd jest-typescript-es-modulesnpm installnpm 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
.coffeefiles out there that userequire/CommonJS, including the CoffeeScript codebase itself. My plan is to treat.coffeeas equivalent to.js, as in, ābehave however a.jsfile 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 mixingimportandrequirestatements 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
.jsfiles 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@nextnow, 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-jestasts-jestonly needs to transformts/tsxtomjs/cjsdepending on tsconfigtarget?Maybe only the case when transforming files from
node_modules, it is necessary to checktype: moduleinpackage.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
moduleFormatin 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-jesthas 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,.tsxor.jsxfor that matter. What about people using.coffee,.vueetc.?Right now the logic is
.mjsis always ESM.cjsis always CJS.jsis ESM if closestpackage.jsonhas atype: 'module'field, otherwise CJSWhat Iām thinking makes sense is to make that last one behave like
js, i.e. infer from thetypefield. 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