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

vite: vue is undefined in runtime #583

Closed
AndreyYolkin opened this issue Oct 18, 2022 · 8 comments
Closed

vite: vue is undefined in runtime #583

AndreyYolkin opened this issue Oct 18, 2022 · 8 comments

Comments

@AndreyYolkin
Copy link
Contributor

Environment


  • Operating System: Linux
  • Node Version: v16.15.1
  • Nuxt Version: 2.16.0-27720022.54e852f
  • Nitro Version: 0.5.4
  • Package Manager: npm@8.13.2
  • Builder: vite
  • User Config: bridge, build, buildModules, vuetify, serverHandlers, devServerHandlers
  • Runtime Modules: -
  • Build Modules: (), @nuxtjs/vuetify@1.12.3, @nuxt/bridge@0.10.1

Reproduction

https://github.com/AndreyYolkin/nuxt-vuetify-issue (better explained)
https://github.com/AndreyYolkin/nuxtjs-vuetify (with @nuxtjs/vuetify)

Describe the bug

For some reasons files that use Vue import in undefined at runtime. I've got this problem trying to make vuetify 2 work with latest bridge versions.
image

Additional context

No response

Logs

entry.mjs:100 TypeError: Cannot read properties of undefined (reading 'observable')
    at Vue.<anonymous> (index.ts:239:23)
    at Vue.on (vue.runtime.esm.js?v=6c5bc416:3655:16)
    at invokeWithErrorHandling (vue.runtime.esm.js?v=6c5bc416:3015:30)
    at Vue.$emit (vue.runtime.esm.js?v=6c5bc416:3714:17)
    at callHook$1 (vue.runtime.esm.js?v=6c5bc416:4033:12)
    at Vue._init (vue.runtime.esm.js?v=6c5bc416:5678:9)
    at new Vue (vue.runtime.esm.js?v=6c5bc416:5747:10)
    at mountApp (entry.mjs:737:16)
Copy link
Member

You may need to transpile these libraries (e.g. vuetify) to ensure you are using the same version of vue.

@AndreyYolkin
Copy link
Contributor Author

AndreyYolkin commented Oct 18, 2022

https://github.com/AndreyYolkin/nuxt-vuetify-issue/blob/master/nuxt.config.ts#L10
https://github.com/AndreyYolkin/nuxtjs-vuetify/blob/master/nuxt.config.ts#L8

Yes, I tried, and still have troubles

@hieunhit
Copy link

hieunhit commented Oct 23, 2022

have the same issue with vue-demi

refs: vitejs/vite#10406

image

@IlyaSemenov
Copy link
Contributor

IlyaSemenov commented Nov 7, 2022

+1 on this. I traced this to default export being deliberately removed in esbuild's __reExport.

Related issue: evanw/esbuild#1737

I ended up with a bunch of pnpm patches:

  1. exporting { Vue } from vue itself
  2. importing { Vue } from 'vue' in the affected libraries
diff --git a/dist/vue.runtime.esm.js b/dist/vue.runtime.esm.js
index 1786d28198333ad006b15289e77790083e88594f..2d1e626ee4932bac121aaececf9edaa08acb729a 100644
--- a/dist/vue.runtime.esm.js
+++ b/dist/vue.runtime.esm.js
@@ -8782,4 +8782,5 @@ if (inBrowser) {
     }, 0);
 }
 
+export { Vue }
 export { EffectScope, computed, customRef, Vue as default, defineAsyncComponent, defineComponent, del, effectScope, getCurrentInstance, getCurrentScope, h, inject, isProxy, isReactive, isReadonly, isRef, isShallow, markRaw, mergeDefaults, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, provide, proxyRefs, reactive, readonly, ref$1 as ref, set, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toRefs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useListeners, useSlots, version, watch, watchEffect, watchPostEffect, watchSyncEffect };
diff --git a/dist/vue.runtime.mjs b/dist/vue.runtime.mjs
index 83d889271bd477fe1506c030fd6b351cdf1fe99b..3b6ed86a7e52e8004934f927b3867aa2d313aee1 100644
--- a/dist/vue.runtime.mjs
+++ b/dist/vue.runtime.mjs
@@ -1,5 +1,6 @@
 import Vue from './vue.runtime.common.js'
 export default Vue
+export { Vue }
 
 // this should be kept in sync with src/v3/index.ts
 export const {

and then like:

diff --git a/dist/portal-vue.esm.js b/dist/portal-vue.esm.js
index 05e6c55723bc8f303569f8deb9dd2b186a9856a8..f69c765ea376cffc50f5e64fd0c04a28edda88d3 100644
--- a/dist/portal-vue.esm.js
+++ b/dist/portal-vue.esm.js
@@ -10,7 +10,7 @@
   * 
  */
 
-import Vue from 'vue';
+import { Vue } from 'vue';
 
 function _typeof(obj) {
   if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {

@AndreyYolkin
Copy link
Contributor Author

+1 on this. I traced this to default export being deliberately removed in esbuild's __reExport.

Related issue: evanw/esbuild#1737

I ended up with a bunch of pnpm patches:

  1. exporting { Vue } from vue itself
  2. importing { Vue } from 'vue' in the affected libraries
diff --git a/dist/vue.runtime.esm.js b/dist/vue.runtime.esm.js
index 1786d28198333ad006b15289e77790083e88594f..2d1e626ee4932bac121aaececf9edaa08acb729a 100644
--- a/dist/vue.runtime.esm.js
+++ b/dist/vue.runtime.esm.js
@@ -8782,4 +8782,5 @@ if (inBrowser) {
     }, 0);
 }
 
+export { Vue }
 export { EffectScope, computed, customRef, Vue as default, defineAsyncComponent, defineComponent, del, effectScope, getCurrentInstance, getCurrentScope, h, inject, isProxy, isReactive, isReadonly, isRef, isShallow, markRaw, mergeDefaults, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, provide, proxyRefs, reactive, readonly, ref$1 as ref, set, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toRefs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useListeners, useSlots, version, watch, watchEffect, watchPostEffect, watchSyncEffect };
diff --git a/dist/vue.runtime.mjs b/dist/vue.runtime.mjs
index 83d889271bd477fe1506c030fd6b351cdf1fe99b..3b6ed86a7e52e8004934f927b3867aa2d313aee1 100644
--- a/dist/vue.runtime.mjs
+++ b/dist/vue.runtime.mjs
@@ -1,5 +1,6 @@
 import Vue from './vue.runtime.common.js'
 export default Vue
+export { Vue }
 
 // this should be kept in sync with src/v3/index.ts
 export const {

and then like:

diff --git a/dist/portal-vue.esm.js b/dist/portal-vue.esm.js
index 05e6c55723bc8f303569f8deb9dd2b186a9856a8..f69c765ea376cffc50f5e64fd0c04a28edda88d3 100644
--- a/dist/portal-vue.esm.js
+++ b/dist/portal-vue.esm.js
@@ -10,7 +10,7 @@
   * 
  */
 
-import Vue from 'vue';
+import { Vue } from 'vue';
 
 function _typeof(obj) {
   if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {

Yes, with the way you suggested, #561 (comment) and commenting this lines

bridge/src/vite/client.ts

Lines 113 to 115 in 586434b

if (!originalURL.startsWith(clientConfig.base!)) {
event.req.url = joinURL('/__url', originalURL)
}
I (probably) achieved working state without errors both in dev/prod mode.

On the one hand, this issue might be labeled with upstream-bug as the problem came from esbuild. On the other hand, there is https://nuxt.com/docs/api/configuration/nuxt-config#externalvue option in config, which didn't solve the problem. Sooo it needs to dive into and figure out why it's happening even with experimental.externalvue: false

@AndreyYolkin
Copy link
Contributor Author

AndreyYolkin commented Feb 3, 2023

I ended up with this solution, which inherits @IlyaSemenov ideas, but saves us from patching source files:

create Nuxt module with @nuxt/kit (or use existing one from your codebase)

add this to your setup function inside this module:

    if (nuxt.options.dev) {
      addVitePlugin({
        name: 'vue-default-normalizer',
        enforce: 'pre',
        transform(src, id) {
          if (src.includes('vue_exports.default')) {
            return {
              code: src.replaceAll('vue_exports.default', 'vue_exports.Vue')
            }
          }
          if (
            id.includes('vue/dist/vue.runtime.esm.js') ||
            id.includes('vue/dist/vue.runtime.mjs')
          ) {
            return {
              code: src + '\nexport { Vue }\n'
            }
          }
          return null
        }
      })
    }

Please keep in mind, that this will not create named { Vue } import and didn't modify the source code. So, you still need to write a code with default Vue import. Otherwise, you will get errors during the build stage.

@danielroe at this moment even playground in this repo is broken (because of vue-demi). I understand that there can be more clean code, but I suggest mark this as workaround or refactor a bit and include to the vite builder

@wattanx
Copy link
Collaborator

wattanx commented May 22, 2023

I tried creating a new one with a similar configuration to https://github.com/AndreyYolkin/nuxt-vuetify-issue, but it seems like the issue doesn't occur with the latest version.
https://stackblitz.com/edit/github-3fgb91-m7baf3

@AndreyYolkin
Copy link
Contributor Author

I tried creating a new one with a similar configuration to https://github.com/AndreyYolkin/nuxt-vuetify-issue, but it seems like the issue doesn't occur with the latest version. https://stackblitz.com/edit/github-3fgb91-m7baf3

Yes, that's why I closed the PR, but forgot to close this issue. Thank you for reminding me 🙂

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.

5 participants