Packaged component, whose template has multiple root nodes, compiles incorrectly when NPM installs from file system
Version
3.0.4
Reproduction link
https://github.com/ddosanjh/bar-app
Steps to reproduce
Repro requires building ddosanjh/bar-app which renders packaged component ddosanjh/foo-test; first we try installing the dependency via the file system:
Starting in a new empty dir...
git clone https://github.com/ddosanjh/foo-test.git
git clone https://github.com/ddosanjh/bar-app.git
cd bar-app
npm i ../foo-test
npm run serve
Open http://localhost:8080/ in browser and notice console warning:
Invalid VNode type: Symbol(Fragment) (symbol) at
at
Nothing is rendered.
Now install foo-test component from git repro instead of filesystem:
npm remove foo-test
npm i ddosanjh/foo-test
npm run serve
Open again in browser.
Notice no error; FooTest packaged component renders correctly:
root 1 root 2
What is expected?
FooTest component defined in https://github.com/ddosanjh/foo-test should render when downloaded locally and referenced as an npm file system dependency.
What is actually happening?
It does not render with console error Invalid VNode type: Symbol(Fragment) (symbol)
The problem is that you bundle Vue into the foo-bar package. This means that bar-app now contain two versions of Vue which are in conflict.
The solution is to properly configure rollup in foot-test to exclude Vue from the final bundle.
Why do you say vue is bundled into foo-test? The rollup output is only 765 bytes and contains only the code for the FooTest component.
Just to be safe however, I moved vue to devDepdency, but get same output upon bundling with rollup. Repro steps hold.
I have tried numerous rollup configurations and no matter what, if the dependency is installed via the local file system, I get this issue.
Also, please note, this issue does not happen when the dependency is specified as a git repo. Which suggests the problem lies with NPM, probably along the lines you suggest, whereby it shares the vue dependency when pulled from git, but creates a separate dependency when installed via file system.
Okay, had another look.
I had the root of the problem is correct: There are two versions of Vue in bar-app. However, that doesn't happen because of it being bundled in foo-test, as I previously stated.
I happens because you import the bundled output from the other git repo locally, and when importing the component, the build system loads the copy of vue from foo-test/node_modules
instead of bar-app/node_modules
.
This problem would not manifest if foo-test
were published on npm and installed into a project, as in that situation, npm would only hoist one copy of Vue ot the top of the node_modules
folder.
So this is a challenge in local development only, and essentially a documentation issue, because some hacking is required to make the build system only load one copy of Vue.
Solutions can be a monorepo setup or npm/yarn link
one of the vue versions to the other. Can't get into more detail right now, will do so later.
Thanks for your investigation. For me, the workaround is to simply specify the NPM dependency as a git repository instead of local file-system reference. It is convenient having it as a local package when updating the code a lot, but not worth any hackery.
Hopefully anyone encountering the same issue will search for Invalid VNode type: Symbol(Fragment) and land on this thread. It's really not obvious what the problem is.
I'll leave it up to you to close or not.
Cheers