Skip to content

Conversation

shaydoc
Copy link

@shaydoc shaydoc commented May 28, 2019

Adding support for customizing the Global Vue alias in WebComponent builds.
The reason for this is to avoid conflict with other components that may bundle Vue as part of their library. I am having this issue at present.

Copy link
Member

@LinusBorg LinusBorg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for submitting a PR.

Currently, it's lacking tests as well as documentation for the feature you added.

Also, your usecase, while mentioned, is not clearly layed out, so I'm not sure I understand it.

@shaydoc
Copy link
Author

shaydoc commented May 30, 2019

@LinusBorg I want externalize Vue as Vue$ or some other name to avoid a collision.

I have a bundled vue application that uses a another component that is bundled but also includes Vue.

When I set window.Vue = Vue in my main.js of my core application, it breaks the other code split component which had Vue bundled as part of its code.

I have to set this in my main.js because I bring in webcomponents built within Vue.

The reason I bring Vue Web components is specifically for use inside a tinymce editor.

Do you understand what I mean?

@shaydoc
Copy link
Author

shaydoc commented Jul 24, 2019

Hey @LinusBorg

I am now thinking if I overwrite the build command in my CLI3 plugin Service that really ought to take care of this use case 🤔, I guess I can then perform the necessary changes without this PR?

So I am revisiting this because I really need it :)
I have made a change to add a command line alias option, I have updated the tests to reflect this.

'--alias': "use with --target 'wc' or 'wc-async' to externalize Vue under a custom alias, e.g. $MyVue"

Within demo-wc.html

<meta charset="utf-8"> <title><%- htmlWebpackPlugin.options.libName %> demo</title> <script src="https://unpkg.com/vue"></script> <% if (htmlWebpackPlugin.options.alias !== 'Vue') { %> <script> window[<%= JSON.stringify(htmlWebpackPlugin.options.alias) %>] = Vue; </script> <% } %> <script src="./<%- htmlWebpackPlugin.options.libName %>.js"></script> <% for (const comp of htmlWebpackPlugin.options.components) { %> <<%= comp %>></<%= comp %>> <% } %> 

To elaborate further.

  1. I have a Vue SPA
  2. Within that application we have a custom WYSIWG RichTextEditor
  3. I am using Webcomponent custom elements (using Vue) as plugins for this Editor
  4. I will build and ship a plugin library for this Editor
  5. There is a 3rd party dependency in this SPA that actually has had to ship with Vue bundled inside its package.
  6. In my main.js of my SPA when I say window.Vue = Vue to allow my custom elements to be aware of Vue Globally as is required I get a collision/breaking issue within the 3rd party dependency.
  7. So what I want to say is window.$MyVueAlias = Vue
  8. The 3rd party dependency is unable to externalize Vue, nor do they wish to in case they wish to use a later version of Vue

These are the core reasons why i need to externalize Vue under a custom alias.

Thanks
Shay

@LinusBorg
Copy link
Member

Hey @shaydoc

Thanks for working on this and pushing it. I definitely understand the use case now as well, so thanks for that.

I'll try and review this before the end of the week. Want to take some time in order to think about possible implications.

@LinusBorg LinusBorg self-assigned this Jul 25, 2019
@LinusBorg
Copy link
Member

Okay so I think the code looks fine technically. I'm still thinking about the use cases.

In your specific case, I'd like to understand how the 3rd party component, which has not externalized Vue, but instead comes with it's own version bundled inside, creates issues when a global Vue instance is present? If they use their internally bundle version, I don't see how their code could care about the globally available version.

Do they assign their bundled version to window.Vue?

I ask about this as I want to make sure this actually solves a use case that is not super-rare and caused by bad practices in some other place...

@shaydoc
Copy link
Author

shaydoc commented Jul 29, 2019

They do not assign window.Vue it is undefined.

Screenshot 2019-07-29 at 12 03 30

So in my app when I set window.Vue = Vue I get this error from the 3rd party component

the code performing the import:

... components: { ThirdPartyComponent: () => import(/* webpackChunkName: "third-party-comp" */ '@widgets/AppHeader/ThirdParty/ThirdPartyComponent'), }, .... 
@shaydoc
Copy link
Author

shaydoc commented Aug 5, 2019

@LinusBorg any further thoughts on this one ?

@xcxooxl
Copy link

xcxooxl commented Sep 16, 2019

Actually I am building a library(more like a separate web app) for my website which both are built in vue, And I'm experiencing the same error (Cannot redefine property.. $router), Would like an update on this also

@shaydoc
Copy link
Author

shaydoc commented Sep 21, 2019

@LinusBorg any updates on when this might be able to be merged ?
How could i use this in the immediate term, can I npm install this branch globally ?

@haoqunjiang
Copy link
Member

It's already possible with the following config in vue.config.js:

module.exports = { chainWebpack: (config) => { config.externals({ vue: 'global $MyVueAlias' }) } }

So no need to add a new flag.

@haoqunjiang haoqunjiang closed this Sep 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
4 participants