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 can use the wrong module if local or linked modules include their own node_modules, breaking Vue #7454

Closed
7 tasks done
JeffSchofield opened this issue Mar 25, 2022 · 5 comments · Fixed by #11032
Closed
7 tasks done

Comments

@JeffSchofield
Copy link

Describe the bug

I am building a UI library package and a Vue app at the same time. Both projects are following best practices from Vite. The UI package and the Vue app both rely on Headless UI.

If the UI package is linked or added as a local file, the node_modules folder comes along with the dist folder. When this happens, Vite will analyse the node_modules folder within the UI package first to resolve Headless UI, which I think grabs a separate instance of Vue and results in errors like provide() can only be used inside setup().

Evidence from the logs below:

vite:deps Scan completed in 123.33ms: {
  vue: 'E:/Work/vite-module-bug/website/node_modules/vue/dist/vue.runtime.esm-bundler.js',
  '@headlessui/vue': 'E:/Work/vite-module-bug/ui-library/node_modules/@headlessui/vue/dist/headlessui.esm.js'
}

Ideally @headlessui/vue should resolve to the one in in /website instead of /ui-library.

Reproduction

https://github.com/JeffSchofield/vite-module-bug

System Info

System:
    OS: Windows 10 10.0.19044
    CPU: (8) x64 Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
    Memory: 3.24 GB / 31.94 GB
  Binaries:
    Node: 16.14.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.17 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 8.3.1 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (99.0.1150.46)
    Internet Explorer: 11.0.19041.1566
  npmPackages:
    @vitejs/plugin-vue: ^2.2.4 => 2.2.4
    vite: ^2.8.6 => 2.8.6

Used Package Manager

npm

Logs

vite:config bundled config file loaded in 104.92ms +0ms
  vite:config using resolved config: {
  vite:config   plugins: [
  vite:config     'vite:pre-alias',
  vite:config     'alias',
  vite:config     'vite:modulepreload-polyfill',
  vite:config     'vite:resolve',
  vite:config     'vite:html-inline-proxy',     
  vite:config     'vite:css',
  vite:config     'vite:esbuild',
  vite:config     'vite:json',
  vite:config     'vite:wasm',
  vite:config     'vite:worker',
  vite:config     'vite:worker-import-meta-url',
  vite:config     'vite:asset',
  vite:config     'vite:vue',
  vite:config     'vite:define',
  vite:config     'vite:css-post',
  vite:config     'vite:client-inject',
  vite:config     'vite:import-analysis'        
  vite:config   ],
  vite:config   server: {
  vite:config     preTransformRequests: true,
  vite:config     force: true,
  vite:config     fs: { strict: true, allow: [Array], deny: [Array] }
  vite:config   },
  vite:config   define: { __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false },
  vite:config   ssr: { external: [ 'vue', '@vue/server-renderer' ] },
  vite:config   configFile: 'E:/Work/vite-module-bug/website/vite.config.ts',
  vite:config   configFileDependencies: [ 'vite.config.ts' ],
  vite:config   inlineConfig: {
  vite:config     root: undefined,
  vite:config     base: undefined,
  vite:config     mode: undefined,
  vite:config     configFile: undefined,
  vite:config     logLevel: undefined,
  vite:config     clearScreen: undefined,
  vite:config     server: { force: true }
  vite:config   },
  vite:config   root: 'E:/Work/vite-module-bug/website',
  vite:config   base: '/',
  vite:config   resolve: { dedupe: undefined, alias: [ [Object], [Object] ] },
  vite:config   publicDir: 'E:\\Work\\vite-module-bug\\website\\public',
  vite:config   cacheDir: 'E:\\Work\\vite-module-bug\\website\\node_modules\\.vite',
  vite:config   command: 'serve',
  vite:config   mode: 'development',
  vite:config   isProduction: false,
  vite:config   build: {
  vite:config     target: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
  vite:config     polyfillModulePreload: true,
  vite:config     outDir: 'dist',
  vite:config     assetsDir: 'assets',
  vite:config     assetsInlineLimit: 4096,
  vite:config     cssCodeSplit: true,
  vite:config     cssTarget: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
  vite:config     sourcemap: false,
  vite:config     rollupOptions: {},
  vite:config     minify: 'esbuild',
  vite:config     terserOptions: {},
  vite:config     write: true,
  vite:config     emptyOutDir: null,
  vite:config     manifest: false,
  vite:config     lib: false,
  vite:config     ssr: false,
  vite:config     ssrManifest: false,
  vite:config     reportCompressedSize: true,
  vite:config     chunkSizeWarningLimit: 500,
  vite:config     watch: null,
  vite:config     commonjsOptions: { include: [Array], extensions: [Array] },
  vite:config     dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] }
  vite:config   },
  vite:config   preview: {
  vite:config     port: undefined,
  vite:config     strictPort: undefined,
  vite:config     host: undefined,
  vite:config     https: undefined,
  vite:config     open: undefined,
  vite:config     proxy: undefined,
  vite:config     cors: undefined,
  vite:config     headers: undefined
  vite:config   },
  vite:config   env: { BASE_URL: '/', MODE: 'development', DEV: true, PROD: false },
  vite:config   assetsInclude: [Function: assetsInclude],
  vite:config   logger: {
  vite:config     hasWarned: false,
  vite:config     info: [Function: info],
  vite:config     warn: [Function: warn],
  vite:config     warnOnce: [Function: warnOnce],
  vite:config     error: [Function: error],
  vite:config     clearScreen: [Function: clearScreen],
  vite:config     hasErrorLogged: [Function: hasErrorLogged]
  vite:config   },
  vite:config   packageCache: Map(0) {},
  vite:config   createResolver: [Function: createResolver],
  vite:config   optimizeDeps: {
  vite:config     esbuildOptions: { keepNames: undefined, preserveSymlinks: undefined }
  vite:config   },
  vite:config   worker: {
  vite:config     format: 'iife',
  vite:config     plugins: [
  vite:config       [Object], [Object],
  vite:config       [Object], [Object],
  vite:config       [Object], [Object],
  vite:config       [Object], [Object],
  vite:config       [Object], [Object],
  vite:config       [Object], [Object],
  vite:config       [Object], [Object],
  vite:config       [Object], [Object]
  vite:config     ],
  vite:config     rollupOptions: {}
  vite:config   }
  vite:config } +8ms
  vite:deps Crawling dependencies using entries:
  vite:deps   E:/Work/vite-module-bug/website/index.html +0ms
  vite:resolve 1.20ms /src/entry-client.ts -> E:/Work/vite-module-bug/website/src/entry-client.ts +0ms
  vite:resolve 5.07ms ./main -> E:/Work/vite-module-bug/website/src/main.ts +12ms
  vite:resolve 19.97ms vue -> E:/Work/vite-module-bug/website/node_modules/vue/dist/vue.runtime.esm-bundler.js +28ms
  vite:resolve 2.29ms ./App.vue -> E:/Work/vite-module-bug/website/src/App.vue +8ms
  vite:resolve 4.97ms ui-library -> E:/Work/vite-module-bug/ui-library/dist/index.es.js +17ms
  vite:resolve 7.23ms @headlessui/vue -> E:/Work/vite-module-bug/ui-library/node_modules/@headlessui/vue/dist/headlessui.esm.js +20ms
  vite:deps Scan completed in 123.33ms: {
  vue: 'E:/Work/vite-module-bug/website/node_modules/vue/dist/vue.runtime.esm-bundler.js',
  '@headlessui/vue': 'E:/Work/vite-module-bug/ui-library/node_modules/@headlessui/vue/dist/headlessui.esm.js'
} +112ms
Pre-bundling dependencies:
  vue
  @headlessui/vue
(this will be run only when your dependencies or config have changed)
  vite:resolve 3.16ms @vue/runtime-dom -> E:/Work/vite-module-bug/website/node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js +0ms
  vite:resolve 5.77ms @vue/runtime-core -> E:/Work/vite-module-bug/website/node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js +20ms
  vite:resolve 5.99ms vue -> E:/Work/vite-module-bug/ui-library/node_modules/vue/dist/vue.runtime.esm-bundler.js +9ms
  vite:resolve 6.31ms @vue/shared -> E:/Work/vite-module-bug/website/node_modules/@vue/shared/dist/shared.esm-bundler.js +7ms
  vite:resolve 6.34ms @vue/runtime-dom -> E:/Work/vite-module-bug/ui-library/node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js +9ms
  vite:resolve 3.79ms @vue/runtime-core -> E:/Work/vite-module-bug/ui-library/node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js +26ms
  vite:resolve 3.44ms @vue/shared -> E:/Work/vite-module-bug/ui-library/node_modules/@vue/shared/dist/shared.esm-bundler.js +5ms
  vite:resolve 5.76ms @vue/reactivity -> E:/Work/vite-module-bug/website/node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js +55ms
  vite:resolve 4.60ms @vue/reactivity -> E:/Work/vite-module-bug/ui-library/node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js +31ms
  vite:deps deps bundled in 294.85ms +0ms

  vite v2.8.6 dev server running at:

  > Local: http://localhost:3000/
  > Network: use `--host` to expose

  ready in 1137ms.

  vite:time 0.59ms / +0ms
  vite:spa-fallback Rewriting GET / to /index.html +0ms
  vite:time 30.37ms /index.html +62ms
  vite:resolve 1.30ms E:\Work\vite-module-bug\website\node_modules\vite\dist\client\client.mjs -> E:/Work/vite-module-bug/website/node_modules/vite/dist/client/client.mjs +0ms
  vite:resolve 2.64ms /@vite/client -> E:/Work/vite-module-bug/website/node_modules/vite/dist/client/client.mjs +1ms
  vite:load 3.73ms [fs] /@vite/client +0ms
  vite:resolve 1.20ms E:\Work\vite-module-bug\website\node_modules\vite\dist\client\env.mjs -> E:/Work/vite-module-bug/website/node_modules/vite/dist/client/env.mjs +18ms
  vite:resolve 3.43ms @vite/env -> E:/Work/vite-module-bug/website/node_modules/vite/dist/client/env.mjs +2ms
  vite:resolve 1.05ms /node_modules/vite/dist/client/env.mjs -> E:/Work/vite-module-bug/website/node_modules/vite/dist/client/env.mjs +1ms
  vite:import-analysis 9.72ms [1 imports rewritten] node_modules\vite\dist\client\client.mjs +0ms
  vite:transform 14.59ms /@vite/client +0ms
  vite:time 33.94ms /@vite/client +63ms    
  vite:resolve 1.27ms /src/main.css?direct -> E:/Work/vite-module-bug/website/src/main.css?direct +20ms
  vite:load 11.60ms [fs] /node_modules/vite/dist/client/env.mjs +39ms
  vite:import-analysis 0.25ms [no imports] node_modules\vite\dist\client\env.mjs +24ms
  vite:transform 1.39ms /node_modules/vite/dist/client/env.mjs +24ms
  vite:load 6.43ms [fs] /src/main.css?direct +4ms
  vite:import-analysis [skipped] src\main.css?direct +15ms
  vite:transform 12.67ms /src/main.css?direct +15ms
  vite:time 25.31ms /src/main.css +35ms
  vite:resolve 0.90ms /src/entry-client.ts -> E:/Work/vite-module-bug/website/src/entry-client.ts +26ms
  vite:load 0.81ms [fs] /src/entry-client.ts +20ms
  vite:resolve 1.80ms ./main -> E:/Work/vite-module-bug/website/src/main.ts +20ms
  vite:resolve 1.01ms /src/main.ts -> E:/Work/vite-module-bug/website/src/main.ts +2ms
  vite:import-analysis 6.50ms [1 imports rewritten] src\entry-client.ts +29ms
  vite:transform 22.49ms /src/entry-client.ts +30ms
  vite:time 29.72ms /src/entry-client.ts +32ms
  vite:load 1.74ms [fs] /src/main.ts +30ms
  vite:resolve 0.22ms vue -> E:/Work/vite-module-bug/website/node_modules/.vite/vue.js?v=a40dd0ad +22ms
  vite:resolve 1.34ms /node_modules/.vite/vue.js?v=a40dd0ad -> E:/Work/vite-module-bug/website/node_modules/.vite/vue.js?v=a40dd0ad +2ms
  vite:resolve 1.01ms ./App.vue -> E:/Work/vite-module-bug/website/src/App.vue +2ms
  vite:resolve 0.97ms /src/App.vue -> E:/Work/vite-module-bug/website/src/App.vue +2ms
  vite:import-analysis 10.60ms [2 imports rewritten] src\main.ts +29ms
  vite:transform 20.52ms /src/main.ts +28ms
  vite:load 1.34ms [fs] /src/App.vue +29ms
  vite:load 50.32ms [fs] /node_modules/.vite/vue.js?v=a40dd0ad +48ms
  vite:resolve 2.36ms ./chunk-AWPMEBIP.js -> E:/Work/vite-module-bug/website/node_modules/.vite/chunk-AWPMEBIP.js +106ms
  vite:resolve 2.95ms /node_modules/.vite/chunk-AWPMEBIP.js?v=a40dd0ad -> E:/Work/vite-module-bug/website/node_modules/.vite/chunk-AWPMEBIP.js?v=a40dd0ad +5ms
  vite:import-analysis 40.26ms [1 imports rewritten] node_modules\.vite\vue.js?v=a40dd0ad +132ms
  vite:transform 43.98ms /node_modules/.vite/vue.js?v=a40dd0ad +132ms
  vite:cache [memory] /node_modules/vite/dist/client/env.mjs +0ms
  vite:time 2.02ms /node_modules/vite/dist/client/env.mjs +163ms
  vite:cache [memory] /src/main.ts +4ms
  vite:time 5.23ms /src/main.ts +7ms
  vite:resolve 0.41ms ui-library -> E:/Work/vite-module-bug/ui-library/dist/index.es.js +55ms
  vite:resolve 0.84ms /@id/plugin-vue:export-helper -> null +7ms
  vite:hmr [self-accepts] src\App.vue +0ms
  vite:import-analysis 19.48ms [3 imports rewritten] src\App.vue +47ms
  vite:transform 173.13ms /src/App.vue +48ms
  vite:cache [memory] /node_modules/.vite/vue.js?v=a40dd0ad +48ms
  vite:load 0.09ms [plugin] plugin-vue:export-helper +142ms
  vite:import-analysis 0.04ms [no imports] plugin-vue:export-helper +23ms
  vite:transform 3.50ms plugin-vue:export-helper +24ms
  vite:cache [memory] /node_modules/.vite/vue.js?v=a40dd0ad +39ms
  vite:time 29.60ms /node_modules/.vite/vue.js?v=a40dd0ad +112ms
  vite:load 134.25ms [fs] /node_modules/.vite/chunk-AWPMEBIP.js?v=a40dd0ad +73ms
  vite:import-analysis 0.07ms [no imports] node_modules\.vite\chunk-AWPMEBIP.js?v=a40dd0ad +75ms
  vite:transform 5.30ms /node_modules/.vite/chunk-AWPMEBIP.js?v=a40dd0ad +74ms
  vite:load 86.44ms [fs] ..\ui-library\dist\index.es.js +10ms
  vite:resolve 0.13ms @headlessui/vue -> E:/Work/vite-module-bug/website/node_modules/.vite/@headlessui_vue.js?v=a40dd0ad +119ms
  vite:resolve 4.95ms /node_modules/.vite/@headlessui_vue.js?v=a40dd0ad -> E:/Work/vite-module-bug/website/node_modules/.vite/@headlessui_vue.js?v=a40dd0ad +11ms
  vite:import-analysis 29.07ms [2 imports rewritten] E:/Work/vite-module-bug/ui-library/dist/index.es.js +36ms
  vite:transform 31.96ms ..\ui-library\dist\index.es.js +37ms
  vite:cache [memory] /node_modules/.vite/vue.js?v=a40dd0ad +91ms
  vite:time 57.90ms /src/App.vue +69ms
  vite:cache [memory] /node_modules/.vite/chunk-AWPMEBIP.js?v=a40dd0ad +15ms
  vite:time 9.98ms /node_modules/.vite/chunk-AWPMEBIP.js?v=a40dd0ad +16ms
  vite:cache [memory] ..\ui-library\dist\index.es.js +12ms
  vite:time 9.68ms ..\ui-library\dist\index.es.js +13ms
  vite:cache [memory] plugin-vue:export-helper +12ms
  vite:time 3.13ms /@id/plugin-vue:export-helper +5ms
  vite:load 45.59ms [fs] /node_modules/.vite/@headlessui_vue.js?v=a40dd0ad +90ms
  vite:import-analysis 12.85ms [1 imports rewritten] node_modules\.vite\@headlessui_vue.js?v=a40dd0ad +82ms
  vite:transform 14.68ms /node_modules/.vite/@headlessui_vue.js?v=a40dd0ad +80ms
  vite:time 56.30ms /node_modules/.vite/@headlessui_vue.js?v=a40dd0ad +65ms
  vite:cache [memory] /node_modules/.vite/chunk-AWPMEBIP.js?v=a40dd0ad +89ms
  vite:resolve 1.80ms /node_modules/.vite/chunk-AWPMEBIP.js -> E:/Work/vite-module-bug/website/node_modules/.vite/chunk-AWPMEBIP.js +332ms
  vite:time 17.43ms /node_modules/.vite/chunk-AWPMEBIP.js.map +221ms

Validations

@bluwy
Copy link
Member

bluwy commented Mar 27, 2022

I haven't tested the repro, but would resolve.dedupe: ["vue"] work?

@JeffSchofield
Copy link
Author

I haven't tested the repro, but would resolve.dedupe: ["vue"] work?

This does indeed resolve the issue, thank you for the pointer!

Since this is really only a problem with local packages during development, is this expected behavior and would this be considered the recommended way to address this issue?

I think my concern is that, for peer dependencies, Vite is following the same path as regular dependencies when building the module graph, which I think doesn't match how NPM models peer dependencies.

@bluwy
Copy link
Member

bluwy commented Mar 30, 2022

Maybe it makes sense for resolve.dedupe: ["vue"] to be a default in plugin-vue, but I don't have much experience with Vue's tooling to say if that's ideal. Perhaps @sodatea could fill us in on this.

topheman added a commit to topheman/webrtc-remote-control that referenced this issue Mar 31, 2022
@danielroe
Copy link
Contributor

A comment. Nuxt emits ESM output. And the dedupeRequire function uses require dynamically, so we get:

require is not defined in ES module scope, you can use import instead
  at dedupeRequire (file://./playground/.output/server/chunks/app/server.mjs:1255:18)  

see

function dedupeRequire(dedupe: string[]) {
const Module = require('module') as { _resolveFilename: NodeResolveFilename }
const resolveFilename = Module._resolveFilename
Module._resolveFilename = function (request, parent, isMain, options) {
if (request[0] !== '.' && request[0] !== '/') {
const parts = request.split('/')
const pkgName = parts[0][0] === '@' ? parts[0] + '/' + parts[1] : parts[0]
if (dedupe.includes(pkgName)) {
// Use this module as the parent.
parent = module
}
}
return resolveFilename!(request, parent, isMain, options)
}
}

This means that enabling this by default would break Nuxt, unless we remove the ssr-require-hook or tweak it to respect ESM output.

@rgripper
Copy link

Similar problem with running preact app and a react ui library in one monorepo. react alias gets resolved to app/preact/compat instead of app/node_modules/preact/compat. Deduping preact works, but is really confusing as the error doesn't indicate the problem. It simply says it failed to load from (an obviously wrong) directory.

haoqunjiang added a commit to haoqunjiang/vite that referenced this issue Nov 22, 2022
Fixes vitejs#2443
Fixes vitejs#7454

It's already been set by default in Nuxt 3 for a while now nuxt/framework#6735
So I think this change should be harmless.
And technically it could be considered a fix than a feat.

Nevertheless, it's better to ship it in v4 to minimize disruptions on
the user side.

Things that are not covered in this PR:
1. SSR, because `resolve.dedupe` doesn't work for ESM build outputs, and
the CommonJS version is kinda hacky, I think it's better to skip the
config for SSR completely. Besides, most related issues are from the
client side.
2. #5958 isn't fixed by this PR.
patak-dev pushed a commit that referenced this issue Nov 22, 2022
fc pushed a commit to fc/vite that referenced this issue Nov 23, 2022
patak-dev pushed a commit to vitejs/vite-plugin-vue that referenced this issue Dec 2, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Dec 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants