-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
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
Bad handle of (dynamic) optional dependencies during dependency pre-bundling #6007
Comments
I'm having this exact same issue in a SvelteKit project! let dependency;
try {
dependency = (await import('@org/dependency')).default;
} catch {
//
} We recently migrated from rollup to Vite and now our old code doesn't work which is super annoying. |
I'm seeing this error when conditionally importing a CSS file that doesn't exist - i.e. the error shows up and prevents compilation even when the condition is falsy: if (import.meta.env.VITE_SOME_FALSY_VAR) {
import('./some-css-file-that-doesnt-exist-in-this-environment.css');
} Seems like dynamic imports are analyzed statically just like static imports. |
@SomaticIT Hi, just tried to use your repo with SvelteKit and running into this issue. Did you ever find a resolution? |
@ZetiMente: Unfortunately, I think there is no simple solution. The only way is to install optional dependencies to allow vite to analyze it. (It will not be bundled during the build) I think, vite should only analyze and bundle dynamic dependencies when they are actually used in the code. However, it means modifying the dependency analyzer process which is a sensible part of the process. I would be happy to take some time to create a PR (when possible) but I need some kind of help from a contributor to avoid mistakes. |
Hmmmm, I also need to find a way to support an optional dependency. Storybook is working on react 18 support, but in a way that also continues to support older versions. We need to dynamically import Edit: turns out I did need |
An [exciting PR](storybookjs/storybook#17215) has been merged and released in `6.5.0-alpha.58 ` that adds storybook support for React 18. However, it currently breaks in the vite-builder test because of an `import()` of the new `react-dom/client`, which only exists in react 18. Due to vitejs/vite#6007, we have to do a little bit of trickery to stop vite from erroring out. The approach I'm taking here is: 1) Rewriting the import of `react-dom/client` to a dummy file if it can't be `require.resolve()`ed. This fixes the problem in production builds. 2) Additionally, adding `react-dom/client` to the list of `optimizeDeps.exclude` if the framework is react and the package can't be required. This is necessary to prevent vite from trying to pre-bundle, and throwing errors in dev. This PR also updates the examples to the new `6.5.0-alpha.58` version of storybook, which includes the PR mentioned above, so that it can be tested in our react examples, and it adds a new `react-18` example as well.
I am running into this issue as well. I am trying to add an optional dependency to tradingstrategy.ai/frontend application. We would like to include an optional third-party library that's proprietary. If someone clones / forks our app who doesn't have access to the proprietary module (in a private repo within our org), we would like them to still be able to run the dev server, build, etc. We thought we'd be able to dynamically import the module inside a The "positive" scenario works (dynamically loading when module available). The "negative" scenario results in the same Let me know if there's a solution or work-around for this. Thanks! |
@kenkunz this is the workaround I arrived at, in addition to Basically, inside a plugin, I have: resolveId(source) {
// Avoid error in react < 18 projects
if (source === 'react-dom/client') {
try {
return require.resolve('react-dom/client', { paths: [projRoot] });
} catch (e) {
// This is not a react 18 project, need to stub out to avoid error
return path.resolve(__dirname, '..', 'input', 'react-dom-client-placeholder.js');
}
}
}, Where the |
Thanks for sharing this, @IanVS … I will try out this approach tomorrow! |
@IanVS thanks again for your suggestion. I wound up using a different work-around – inspired by another issue you opened: #5728 [Feature request] Allow import.meta.glob from node_modules (addressed by PR #6056). I am now loading the optional dep using: const modules = import.meta.glob('/node_modules/chartiq/{js,css}/*.{js,css}'); …and then checking My only slight hesitancy with this approach is that it's a Vite-specific feature. But given that it's a work-around to a Vite-specific issue … and this is in a SvelteKit app (no real likelihood of moving away from Vite) … I'm fine with that. |
My workaround in #6007 (comment) is no longer working in vite 3. I notice a lot fewer dependencies are being passed to |
@IanVS would you be able to provide a minimal setup for this so we can reproduce it? Are you using
|
Yes, I'm using I'm sorry, I don't quite see the connection to the jsx runtime. I'll work on a minimal reproduction. |
Sorry, there is no connection to the jsx runtime. I mean that plugin-react is doing a virtual module for that dependency and only include the real one in it. A similar trick could work for you. I wonder why an alias isn't enough here, could you detect this at config time? // Avoid error in react < 18 projects
if (source === 'react-dom/client') {
try {
return require.resolve('react-dom/client', { paths: [projRoot] });
} catch (e) {
// This is not a react 18 project, need to stub out to avoid error
return path.resolve(__dirname, '..', 'input', 'react-dom-client-placeholder.js');
}
} |
This implements a suggestion in vitejs/vite#6007 (comment) to alias react-dom/client to our placeholder file when the dependency is not found. In vite 3.0, our current approach will no longer work, and we'll need to use this method instead.
Reporting back, setting an alias to point to my file seems like a usable workaround. I wasn't able to use a virtual file using the approach from 'react/jsx-runtime'. One small downside is that rollup warns about generating an empty chunk, but I can live with that. |
@IanVS if you think the virtual file approach or your all workaround should work, please open a new bug report with a reproduction. I think that alias is good here, maybe we should check that warning too. |
This implements a suggestion in vitejs/vite#6007 (comment) to alias react-dom/client to our placeholder file when the dependency is not found. In vite 3.0, our current approach will no longer work, and we'll need to use this method instead.
I tried to create a minimal reproduction, but wasn't able to reproduce the issue when using my previous workaround without an alias on vite 3. It failed in storybook, but not when I tried to reproduce it. I'm happy to use the alias unless there's a downside to it I don't know of. |
I think an alias is a better solution here, but it would be good to avoid that warning :) |
I can probably add a |
Describe the bug
Hello,
First of all, thank you for developping this awesome tool. I use it on many projects now as the replacement of my old but stable toolchain.
Let's get into this issue: I'm maintainer of the library svelte-query which uses an optional dependency (broadcast-channel) to provide an opt-in feature.
When developers install the library on a vite project, vite is throwing an error:
Failed to resolve import "broadcast-channel"
(SvelteStack/svelte-query#63).However, this dependency is imported dynamically only when the developper actually use the associated feature.
I think, there are two options to resolve this issue:
optionalDependencies
in thepackage.json
.The only workaround I found is to install the optional dependency even if it's not used. I tried to include
@sveltestack/svelte-query
,broadcast-channel
or both inoptimizeDeps.exclude
but it's not enough to workaround this issue.I'm not familiar with vite code but I'm happy to help if needed.
Reproduction
1/ Start by creating a fresh project using
create-vite
:$ npm init vite ✔ Project name: … vite-project ✔ Select a framework: › svelte ✔ Select a variant: › svelte-ts $ cd vite-project $ npm install
2/ Install
svelte-query
dependency:3/ Use it in your code (eg:
App.svelte
):4/ Run the project:
System Info
Used Package Manager
npm
Logs
Validations
The text was updated successfully, but these errors were encountered: