Skip to content
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

[Bug]: Outdated documentation for esm-support #3828

Closed
k2snowman69 opened this issue Sep 22, 2022 · 12 comments · Fixed by #3834
Closed

[Bug]: Outdated documentation for esm-support #3828

k2snowman69 opened this issue Sep 22, 2022 · 12 comments · Fixed by #3834

Comments

@k2snowman69
Copy link

k2snowman69 commented Sep 22, 2022

Version

29.0.1

Steps to reproduce

Setup

  1. Add [email protected] and [email protected] to your repo
  2. Ensure "type": "module", is set in your package.json
  3. Add npm script "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
  4. Add a basic file to test add.ts which adds two numbers
  5. Add a basic test add.test.ts which uses import * as Utils from "./add.js";
  6. Follow steps on https://kulshekhar.github.io/ts-jest/docs/guides/esm-support to setup a jest.config.js

Manual config

With Jest 29 the following worked for me. These are the updates I made:

  1. Removing extensionsToTreatAsEsm
  2. Gave a default for regex_match_files that should match most people's scenarios)
{
  moduleNameMapper: {
    "^(\\.{1,2}/.*)\\.js$": "$1",
  },
  transform: {
    // TODO: you may need to modify this regex to match your files
    "\\.tsx?$": [
      "ts-jest",
      {
        useESM: true,
      },
    ],
  },
};

Preset config

  1. Copy the preset config
  2. Update <regex_match_files> with \\.tsx?$
  3. Run jest
  4. Receive unexpected error "ReferenceError: exports is not defined"

I couldn't figure out a work around for this situation without removing the preset completely

Help, I want to get up and running

Did you stumble upon this ticket while looking for an answer? Copy paste the following config and you should be unblocked

{
  moduleNameMapper: {
    "^(\\.{1,2}/.*)\\.js$": "$1",
  },
  transform: {
    // TODO: you may need to modify this regex to match your files
    "\\.tsx?$": [
      "ts-jest",
      {
        useESM: true,
      },
    ],
  },
};

Expected behavior

Documentation to be updated so that both configurations to run successfully after copy pasting into a jest.config.js

Actual behavior

Manual config

  1. Doesn't work after copy paste due to <regex_match_files>

Preset config

  1. Doesn't work after copy paste due to <regex_match_files>
  2. preset attribute seems to cause failures and oddly isn't actually needed

Debug log

N/A - Configuration specific, not runtime

Additional context

No response

Environment

System:
    OS: macOS 12.6
    CPU: (8) x64 Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
  Binaries:
    Node: 16.13.2 - /usr/local/bin/node
    npm: 8.9.0 - /usr/local/bin/npm
  npmPackages:
    jest: ^29.0.3 => 29.0.3
@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 23, 2022

PR is welcome

About < regex_match_files>, this is a generic way to inform users that there can be many ways to define a regex to match files.

However, we can add the regex to the presets page https://kulshekhar.github.io/ts-jest/docs/getting-started/presets and then link the ESM documentation to that page so that users can know what should be the regex.

@k2snowman69
Copy link
Author

I can update the documentation for regex_match_files. However whenever I add preset: "ts-jest/presets/default-esm", into my config I get the following error ReferenceError: exports is not defined. If you know the fix for that I can document that in the same PR.

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 23, 2022

I think updating documentation is ok.

Regarding to the error, it seems like Jest doesn't recognize the ESM config. You can compare your config with example apps https://github.com/kulshekhar/ts-jest/tree/main/examples

@k2snowman69
Copy link
Author

Actually I think the issue is that my repository is ESM and however you're pulling in resets is cjs specific. I created this example repo for you:
https://github.com/k2snowman69/bug-ts-jest-preset/

  • If you run the tests as is, you'll get the ReferenceError: exports is not defined error.
  • If you comment out the preset property in the jest config the tests will run correctly.

If this is a code issue, I think it should be a separate ticket and let's leave this for documentation updates.

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 23, 2022

The presets only set the transform regex and transformer name, it doesn’t set anything else https://github.com/kulshekhar/ts-jest/blob/main/src/presets/create-jest-preset.ts

And it's more for Jest because ts-jest doesn't control how config is merged.

@k2snowman69
Copy link
Author

Maybe the issue is on jest's side and it's not respecting that ts-jest is cjs? In my experience ReferenceError: exports is not defined error is more commonly found when someone is trying to set module.exports in a ESM project. However what the issue is deeper than that I haven't investigated.

If I had to guess the issue is here:
https://github.com/kulshekhar/ts-jest/blob/main/presets/default-esm/jest-preset.js#L1

But again, that's just a guess.

For now I'll just stop using the preset and copy the contents I need but just calling it out as something that might need to be tracked down.

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 23, 2022

You can play with the example app https://github.com/kulshekhar/ts-jest/blob/main/examples/ts-only/jest-esm.config.js because it works there.

@k2snowman69
Copy link
Author

Yes because that project is also still cjs. You need to add type: "module" in the package.json

@k2snowman69
Copy link
Author

For the documentation, for Jest@29 is extensionsToTreatAsEsm still needed if transform already takes a regex of files to send to ts-jest? Everything seems to keep working without it, not sure if I'm missing an edge scenario under the hood I don't know about.

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 23, 2022

That one Jest requires to set always:(

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 23, 2022

Yes because that project is also still cjs. You need to add type: "module" in the package.json

I found the issue. Indeed it was caused by Jest merged config. The transformer config which is passed into TsJestTransformer is {} instead of { tsconfig: "tsconfig.json", useESM: true } which ts-jest cannot detect the project is using ESM mode. This is something we can't do. As far as I remember, presets has higher priority than explicit transform config.

EDITED I think I might find a way to fix it:)

@eugene1g
Copy link

Thank you @k2snowman69 and @ahnpnl for investigating & fixing - this issue has been preventing us from migrating our ESM-only packages to v29. Would it be possible to cut a new patch-level release with this fix? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants