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

build: use cjs/mjs extensions for cjs/esm builds #4814

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

danielroe
Copy link
Member

Summary

This PR proposes using .cjs and .mjs instead of the current .js extensions. That will allow usage of the @vue packages in a native Node module context.

Example

old new
vue.cjs.js vue.cjs
vue.prod.cjs.js vue.prod.cjs
vue.esm-browser.js vue.esm-browser.mjs
vue.esm-browser.prod.js vue.esm-browser.prod.mjs
vue.runtime.esm-browser.js vue.runtime.esm-browser.mjs
vue.runtime.esm-browser.prod.js vue.runtime.esm-browser.prod.mjs
vue.esm-bundler.js vue.esm-bundler.mjs
vue.runtime.esm-bundler.js vue.runtime.esm-bundler.mjs
vue.global.js vue.global.js
vue.global.prod.js vue.global.prod.js
vue.runtime.global.prod.js vue.runtime.global.prod.js
vue.runtime.global.js vue.runtime.global.js

Notes

Background issue

This will improve support for use of vue dependencies in native node esm contexts.

'use strict'

if (process.env.NODE_ENV === 'production') {
module.exports = require('./dist/compiler-dom.prod.cjs')
Copy link

Choose a reason for hiding this comment

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

I would suggest adding conditional exports at the same time so instead of process.env workaround, we can use import conditions to use dev or prod build

@yyx990803
Copy link
Member

This is indeed a breaking change.

  • Is the .cjs rename necessary?
  • .mjs files are really a Node-only construct, so it doesn't make sense to rename esm-browser files as well.
  • Since we do not have conditional exports declared for @vue/* packages, you will need to import these .mjs files via deep import, which isn't really ideal, so we'd have to add conditional exports for them - otherwise this doesn't really do much.
  • To lessen the impact on existing build configs and CDNs relying on these file names, we should probably just add index.mjs files that contain export * from './index.js'

However, with Node's ESM <> CJS interop, current @vue/* packages can already be seamlessly imported, so I'm wondering if this PR is really worth it at all.

@kazupon
Copy link
Member

kazupon commented Aug 31, 2022

Recently, an SSR issue was opened on vue-i18n with the combination of vitepress v1 alpha10 + vue-i18n.
intlify/vue-i18n-next#1131 (comment)

Using the stacktrace output as a clue, I’ve found out the cause, I found the issue occurred in the vitepress build, i.e., the build of vite's SSR.

Since vue-i18n is integrated using the vue-devtools plugin, it depends on vue's __VUE_PROD_DEVTOOLS__ feature flag.

The reason for using this flag is that we want to tree-shake the vue-devtools plugin code implemented in vue-i18n for production.

In vite's SSR builds, the Vue-related modules loaded are cjs modules such as server-renderer.cjs.prod.js and runtime-core.cjs.prod.js.

The __VUE_PROD_DEVTOOLS__ flag is set by runtime-core.esm-bundler.js, the module for esm.

So, vitepress SSR uses runtime-core for cjs, so if you create an SSG application using vue-i18n, it will not work because the __VUE_PROD_DEVTOOLS__ frag is not set.

To solve this issue, I might be able to work around a bundle hack like vue-router on the vue-i18n side.
I would prefer to support it in vue/core if possible.

@pi0
Copy link

pi0 commented Aug 31, 2022

Thanks for sharing this @kazupon. This is off topic just to share, in nuxt 3, we set __VUE_PROD_DEVTOOLS__ flag to optimal value but since valid .mjs could be also externalized and the fact bundler flag is not always working, I made vue-devtools-stub that stubs @vue/devtools both externally and when bundled. It is currently used by Nuxt additinal to the flag.

It would be amazing if mjs build output can use ESM conditions to somehow switch between prod build with/without bundler flag because this way we can externaliz libs for production SSR build without stubing devtools dependency.

@kazupon
Copy link
Member

kazupon commented Sep 1, 2022

@pi0
I seem that Stub is a good workaround!
I’ll try to take your sharing as a reference and try to deal with it.

Thank you for all your helpful sharing as always! 💚

kazupon added a commit to intlify/bundle-tools that referenced this pull request Sep 2, 2022
NOTE:
  This fix is workaround for vite3 SSR.
  Ideally, We hope that this fix will not be necessary once the SSR module on the vue side supports cjs/mjs.
  ref: vuejs/core#4814
kazupon added a commit to intlify/bundle-tools that referenced this pull request Sep 2, 2022
NOTE:
  This fix is workaround for vite3 SSR.
  Ideally, We hope that this fix will not be necessary once the SSR module on the vue side supports cjs/mjs.
  ref: vuejs/core#4814
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

None yet

4 participants