Injection symbol not found in imported component when running "vite dev"
Vue version
3.2.41
Link to minimal reproduction
https://github.com/bauer00/vue3-module-provide-test
Steps to reproduce
- Checkout https://github.com/bauer00/vue3-module-provide-test (It's a clean install with
npm init vue@latest
and only added Typescript) npm install
(this should also install the module@test/module
which is provided by a local packagetest-mdoule-0.0.1.tgz
npm run dev
- Open browser
General description of what I try to do:
I have a plugin which on install()
adds a value via provide
to the app. Then I have a component which injects this value again and displays them. Both, the plugin and the component are in an imported module which is installed via npm
. I also added both the plugin and the component directly into the app, to show that it only happens when I use the imported plugin and component.
What is expected?
Under Module Test Component
it should output
Module inject: MODULE TEST
like it does under Local Test Component
.
There should be no warning in the browser console.
What is actually happening?
The injection symbol can't be found and nothing is displayed in the imported component.
In the browser console this warning is visible:
[Vue warn]: injection "Symbol(module provide test)" not found.
at <ModuleTestComponent>
at <App>
Using the exact same injection symbol in a local component correctly injects the value.
System Info
No response
Any additional comments?
- The imported module is not pre-built in any way, it just contains the source code. The project which imports the module should be in charge of building and bundling everything.
- It works correct when building the project and running it.
- It also works when I exclude the imported module in
optimizeDeps
, but I'm not sure if that's the expected behavior. (I've commented this in the providedvite.config.ts
, so you can test it by just uncommenting this) - I've also done a quick test without typescript and without an injection key, just a normal string and it also seems to work.
Make sure to externalise vue when bundling a library using Vue. It cannot be a dependency
Remember to use the forum or the Discord chat to ask questions!
Thanks for your response, but externalise should only make a difference if the imported library is pre-built. As I'm not doing that, so basically normally importing the components, just from node_modules and build everything at the end, externalising shouldn't have any effects.
To test, I've updated my example code and put the vue dependency in the imported test library as peer- and devDependecy, but as expected there was no change in behavior.
Hello! I'm facing the same problem. I am importing a component from node_modules (which is presented as source code, not a build). It implements provide based on Symbol(). And in the main component, I do an inject() on the same symbol, but the attempt fails. At the same time, if the imported component is not in node_modules, but in src, then such a problem does not arise. What could this be related to?
I think I understand what the problem is. Let's modify the module_test_plugin file.ts in @test/module and add console.log() to it:
import type { InjectionKey } from "vue";
console.log('Look at me!') // Added
export const moduleProvideTestKey = Symbol("module provide test") as InjectionKey<string>;
export const moduleTestPlugin = {
install(app) {
console.log("moduleTestPlugin::install()");
app.provide(moduleProvideTestKey, "MODULE TEST");
},
};
After launching the dev server in the browser console, a message from console.log() will be output 2 times. That is, the moduleProvideTestKey symbol will be defined 2 times. In this case, the first definition of the symbol will be used for provide() in the module files @test/module, and the second definition will be used for inject() in the main project. But since in fact two different symbols will be used, it will not be possible to establish a connection between provide() in @test/mode and inject() in the main project.
How would it be possible to formulate the problem in detail for a bug report in the vite repository?
@PurpleTape you get two console logs because your setup includes two vue copies. use Vite's dedupe
option to make it ensure that the same Vue copy is used for all modules in your app.
I've also tested that and I can reproduce this behaviour. I've added a log to both the module_test_plugin.ts
and test_plugin.ts
. Adding vue
or the @test/module
to resolve.dedupe didn't help.
When I looked at the location where the logs were executed I saw this behaviour:
In the network tab I see only one file loaded, it contains to cache buster like the 1st one, but the path is the 2nd one.
It's likely that this is a vite "problem".