vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.75k stars 6.33k forks source link

Output library does not work when 'import(xyz.vue)' is used for component dependency #1607

Closed MrCoder closed 6 years ago

MrCoder commented 6 years ago

Version

3.0.0-rc.2

Reproduction link

https://github.com/ZenUml/test-lib3

Steps to reproduce

  1. Clone test-lib3 from https://github.com/ZenUml/test-lib3
  2. Clone test-lib3-consumer from https://github.com/ZenUml/test-lib3-consumer
  3. Build test-lib3 with 'yarn build' (note, this is configured to 'vue-cli-service build --target lib --name test-lib3 ./src/main.js')
  4. Run 'yarn serve' in 'test-lib3-consumer'
  5. Check browser console.

What is expected?

It should print out the version - '0.0.1' as hard coded in 'test-lib3'.

What is actually happening?

It prints an error:

Uncaught TypeError: Cannot read property 'bind' of undefined at eval (test-lib3.umd.js?892c:241) at eval (test-lib3.umd.js?892c:252) at webpackUniversalModuleDefinition (test-lib3.umd.js?892c:3) at eval (test-lib3.umd.js?892c:10) at Object../node_modules/test-lib3/dist/test-lib3.umd.js (app.js:1540) at webpack_require (app.js:722) at fn (app.js:99) at eval (main.js:6) at Module../src/main.js (app.js:1889) at webpack_require (app.js:722)


It is happening only when I use the following way to configure a component dependency ( to resolve circular dependency).

components: { HelloWorld: () => import('./components/HelloWorld.vue') }

MrCoder commented 6 years ago

If you come here for any kind of solution, you can disable code splitting by components: { 'block': () => import(/* webpackMode: "eager" */ './Block.vue') }

For more information: https://webpack.js.org/api/module-methods/#import-

u3u commented 6 years ago

The same problem, I developed a Vue component that tries to load additional functionality using dynamic import.

like this:

import Vue from 'vue';
import APlayer from './APlayer';

Vue.use(APlayer, {
   hls: true, // import('hls.js')
})

Using eager will cause the size of the component to become larger. Even if the hls function is not enabled, the entire hls.js will be loaded.

LinusBorg commented 6 years ago

I can't follow the reproduction instructions.

  1. How did you make test-lib3available in the consumer? did you npm link it?
  2. Bundling a Vue app as a lib that's mounting to the same element that the consumer app is mounting to seems like a good way to create a playground for strange things to happen. Why do you even do that? You only export a constant from that lib.

I have in fact a suspicion a to what it happening:

  1. The new Vue() inside test-lib3 mounts to #app first.
  2. in the brackground, the HelloWord component is downloaded, but not yet mounted
  3. then, the new Vue() app of your consumer is mounting to #app - but that element is already controlled by the main instance of test-lib3, and so is essentially overwritten, removed from the DOM.
  4. Now the HelloWorld component of test-lib3 has finished downloading, but the app that should render it isn't even in the DOM anymore - that other instance is.

...and that probably screws everything up.