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

docs: ESM update #13191

Merged
merged 14 commits into from Sep 3, 2022
Merged

docs: ESM update #13191

merged 14 commits into from Sep 3, 2022

Conversation

iamWing
Copy link
Contributor

@iamWing iamWing commented Aug 30, 2022

Summary

As discussed in #13135, this PR:

  • documented that there's no hoisting on jest.mock with ESM support activated and added example of putting the mock calls before import statements to properly load the import modules.
  • updated Using with ES module imports in ManulMocks.md to point out the hoisting mentioned there does not applied when ESM support is activated with link to ECMAScriptModules.md.

Additionally, I've updated the Node version number mentioned in ECMAScriptModules.md to reflect the fact that vm.Module is still considered experimental in 18.8.0.

@mrazauskas I've found that already a link to #10025 in ECMAScriptModules.md, do you want to add some documentations for jest.unstable_mock there as well or you think it's fine just leave it like this for now?

Test plan

No test plan. Only docs are updated.

- Added link to `ECMAScriptModules` in section `Using with ES module imports`.
- To reflect the most updated status.
- Replace hard coded link to `ECMAScriptModules` documentation in
`ManualMocks.md` with a relative link to `ECMAScriptModules.md`.
Copy link
Contributor

@mrazauskas mrazauskas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Yes, it would be very useful to have jest.unstable_mock() documented as well. If a paragraph on jest.mock() is added, then someone trying to mock ESM module might be not happy (;

docs/ECMAScriptModules.md Outdated Show resolved Hide resolved
docs/ECMAScriptModules.md Outdated Show resolved Hide resolved
docs/ECMAScriptModules.md Outdated Show resolved Hide resolved
@mrazauskas
Copy link
Contributor

By the way, jest.unstable_mock() shipped with Jest 27.1.1. See #9430 (comment). It should be documented only in docs of v27 and up.

@iamWing
Copy link
Contributor Author

iamWing commented Aug 30, 2022

Thanks!

Yes, it would be very useful to have jest.unstable_mock() documented as well. If a paragraph on jest.mock() is added, then someone trying to mock ESM module might be not happy (;

Okay. One question tho, am I right that jest.mock doesn't work for ESM but CJS modules with ESM support activated? So jest.unstable_mock is meant to mock the ESM?

@mrazauskas
Copy link
Contributor

Oh.. Sorry there was a typo. The method is called jest.unstable_mockModule(). It mocks only ESModules, hence the Module at the end of the name.

Your example with electron is very good. It shows how mock CJS module from in an ESM test. I think next to it there must be an example how to mock ESM module in an ESM test. Something similar to #10025 (comment)

docs/ManualMocks.md Outdated Show resolved Hide resolved
- Also clarified that the limitation comes from ESM, not Jest.
@iamWing iamWing changed the title Docs/esm update docs: ESM update Aug 31, 2022
@iamWing
Copy link
Contributor Author

iamWing commented Aug 31, 2022

@mrazauskas I've added a fairly simple example for unstable_mockModule at the bottom of ECMAScriptModules.md. I think that should be enough for now? Maybe we can also put it in JestObjectAPI.md but not sure if you guys want it there as well. I'm assuming it's going to be deprecated soon after jest.mock is able to support ESM`.

Copy link

@Javidmj Javidmj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good

docs/ECMAScriptModules.md Outdated Show resolved Hide resolved
docs/ECMAScriptModules.md Show resolved Hide resolved
@@ -38,4 +38,51 @@ import.meta.jest.useFakeTimers();
// jest === import.meta.jest => true
```

Additionally, since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.
Copy link
Member

@SimenB SimenB Sep 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we talk about "dynamic import()", and then go on to use require?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made the change to also mention require there, with the example now showing both require and dynamic import() usage. Personally I prefer require for CJS modules but I think it's better to show both on the docs so the users aren't going to think that either is more preferable.

@mrazauskas
Copy link
Contributor

Thanks for your patience and collaboration. This is shaping up nicely!

- Diabled `no-redeclare`.
- Chagned to the suggested version.
@iamWing
Copy link
Contributor Author

iamWing commented Sep 2, 2022

Thanks for your patience and collaboration. This is shaping up nicely!

Yeah we're getting close to finalise it.

I do think this doc is much needed for people migrating to ESM syntax. In fact, a fellow developer using my Electron boilerplate with ESM enabled got confused with this recently. There should be a lot less confusion for the users once we have the updated doc goes live.

@@ -38,4 +38,57 @@ import.meta.jest.useFakeTimers();
// jest === import.meta.jest => true
```

Please note that we currently don't support `jest.mock` in a clean way in ESM, but that is something we intend to add proper support for in the future. Follow [this issue](https://github.com/facebook/jest/issues/10025) for updates.
Additionally, since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use `require` or dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last idea from my side:

Suggested change
Additionally, since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use `require` or dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.
## Module mocking in ESM
Since ESM evaluates static `import` statements before looking at the code, hoisting on `jest.mock` calls that happens in CJS modules won't work in ESM. To `mock` modules in ESM, you need to use `require` or dynamic `import()` after `jest.mock` calls to load the mocked modules, same applies to modules which have to load the mocked modules.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we have this title added on v27+ only? We can only mock CJS modules before v27 even with ESM support enabled right? Plus I've noticed that the ECMAScript Modules page doesn't show up on v25's sidebar. Is that list a generated one or we have to update the sidebars.json manually?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, it makes sense only with v27+. I will take a look at the sidebars later. Can it be there was no ESM support in v25? No sure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked around quickly. Seems like first steps with ESM support were released in v25. So you are right here too, that link is missing in the sidebar and must be added. Thanks!

- Added section title `MOdule mocking in ESM` on `v27+` only.
Copy link
Member

@SimenB SimenB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is looking great! just some minor nits

docs/ECMAScriptModules.md Outdated Show resolved Hide resolved
docs/ECMAScriptModules.md Outdated Show resolved Hide resolved
docs/ManualMocks.md Outdated Show resolved Hide resolved
@SimenB SimenB merged commit 0cfc2ad into jestjs:main Sep 3, 2022
@SimenB
Copy link
Member

SimenB commented Sep 3, 2022

thanks!

@github-actions
Copy link

github-actions bot commented Oct 4, 2022

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants