Subscribe on changes!

Packaged component, whose template has multiple root nodes, compiles incorrectly when NPM installs from file system

avatar
Dec 15th 2020

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)

avatar
Dec 15th 2020

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.

avatar
Dec 15th 2020

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.

avatar
Dec 16th 2020

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.

avatar
Dec 16th 2020

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

avatar
Dec 17th 2020

This is a topic that needs documentation in the docs/cookbook section, in a recipe for how to build plugins/libraries. It's not solvable in this repo.