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

fix: use .mjs extension for ESM bundles #671

Merged
merged 1 commit into from
Jun 17, 2021

Conversation

haoqunjiang
Copy link
Member

https://nodejs.org/api/packages.html#packages_determining_module_system

Without type: "module" in the package.json, Node.js (and therefore Jest, too) treats these .js files as CommonJS modules, which is incorrect. It is also causing trouble in vite-jest.

@cexbrayat
Copy link
Member

Thanks @sodatea
We all look forward to test vite-jest !

@cexbrayat cexbrayat merged commit 80af029 into vuejs:master Jun 17, 2021
@lmiller1990
Copy link
Member

lmiller1990 commented Jun 23, 2021

This change broke something for me in @cypress/vue. It's using webpack. Now I get this:

image

Any idea @sodatea? This is the problem line: https://github.com/vuejs/vue-test-utils-next/blob/cfa9064e6bcbce282ca634cc5340058f3748d461/src/utils/compileSlots.ts#L1

Should the published @vue/compiler-core also have an mjs extension published? It looks like it doesn't at the moment.

ls node_modules/@vue/compiler-dom/dist/
compiler-dom.cjs.js
compiler-dom.cjs.prod.js
compiler-dom.d.ts
compiler-dom.esm-browser.js
compiler-dom.esm-browser.prod.js
compiler-dom.esm-bundler.js
compiler-dom.global.js
compiler-dom.global.prod.js

🤔

@haoqunjiang
Copy link
Member Author

Yeah… maybe it's better to revert this change at this moment. I found another workaround in vite-jest anyway.

@haoqunjiang
Copy link
Member Author

I'm also working on a post to discuss the issue on native Node ESM support in Vue 3 core packages. Hopefully I can present it in the next team meeting.

@lmiller1990
Copy link
Member

Sounds good. Happy to make this change, but we should make sure the rest of the core ecosystem follows the same conventions.

@haoqunjiang
Copy link
Member Author

haoqunjiang commented Jun 23, 2021

The problem of this PR is that module is not the standard way to declare the ESM entry of a package. It's just a convention among popular tools.

So when we mix the none-standard module field with the standard .mjs notation, different tools may have different opinions on the end result.

For example, in the case of vite-jest, module resolution and transformation is done by vite, which recognizes the module entry by default. But the code is executed in native Node environment. Therefore there will be a similar error raised.

It won't be a problem if the module resolution is also done by Node (the main field will be used).
Neither will it be a problem if the code is executed in browsers, because browsers don't care about the file extension.

I worked around this issue in vite-jest by completely ignoring the module field and use the cjs entry instead.

@lmiller1990
Copy link
Member

I see. Right now we are building will rollup. Maybe there is something I can change in my config, I'll try that before reverting this change.

Although this is not following the standard, breaking popular tools is not ideal either. What is the ideal solution moving forward? All tools and libraries should be adopting .mjs (including Vue core)?

@lmiller1990
Copy link
Member

lmiller1990 commented Jun 24, 2021

I could not find a way to build a library. It could be my lack of understanding on how to configure rollup. This seems to be a problem in other projects, too.

I will revert this (for now). Happy to support the correct mjs extension, but we should make sure it won't break any existing packages (which it does). We should figure this whole thing about before Vue 3 is the main version on npm.

@lmiller1990
Copy link
Member

Reverted in 2.0.0-rc.9. https://github.com/vuejs/vue-test-utils-next/releases/tag/v2.0.0-rc.9

Let's chat more and figure out the best approach for moving the Vue core ecosystem to mjs.

@haoqunjiang
Copy link
Member Author

I talked to Evan and he believes that we need a dedicated time period to make the switch to ESM - just like the switch to Vue 3 as default.
It can be postponed after the release of 3.2 or 3.3.

Because actually, Node.js now works quite well in ESM-CJS interop. As this issue illustrates, we can now seamlessly import from a CJS module to an ESM module as long as it's statically analyzable by https://github.com/guybedford/cjs-module-lexer. The CJS Module Lexer does support quite a lot of patterns.

The error from @cypress/vue looks more like a webpack bug.

But anyway, there's no urgent need for a native ESM entry now. If it's safer to keep it as-is, let's keep it as-is.

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

Successfully merging this pull request may close these issues.

3 participants