Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include Vue instance when Build Target is Lib mode #4055

Closed
ghost opened this issue May 24, 2019 · 21 comments · Fixed by #4261
Closed

Include Vue instance when Build Target is Lib mode #4055

ghost opened this issue May 24, 2019 · 21 comments · Fixed by #4261

Comments

@ghost
Copy link

ghost commented May 24, 2019

What problem does this feature solve?

We are building multiple micro frontend applications that are then stitched together into singular spa experience at run-time. As such, building these applications in using a build target "--target app" is not a viable approach. We need a single file that contains the application source code to load up as we are stitching applications together. For this reason, using a build target "--target lib" seemed like a ideal solution for us. However, we've noticed the build tool contains logic when it is building the application that it excludes Vue instances automatically, which you folks have clearly indicated in your documentation. We weren't able to override this behavior using either the configureWebpack object nor the chainWebpack() callback function.

What does the proposed API look like?

As simple fix would be to move the process of externalizing Vue up prior to applying configureWebpack config object or executing chainWebpack() callback. That way, you are giving programmers the flexibility to include it if it suits their architectural scenario without it being a breaking change.

@ghost ghost changed the title exclude wc mode Include Vue instance when Build Target is Lib mode May 24, 2019
@trickstival
Copy link
Contributor

I've seen that config is defined based on user webpack chain:

const config = api.resolveChainableWebpackConfig()

and then used to remove Vue instances:

Is it possible to create the config another way, apply externals and then apply the chain?

If it's not, maybe a flag on vue.config can do that, so we add an "if" before applying externals

@ghost
Copy link
Author

ghost commented May 28, 2019

Personally, not having reviewed the source code in depth, @trickstival approach seems like a simple, backwards compatible solution to the problem. We would be happy with a change like that!

@trickstival
Copy link
Contributor

trickstival commented May 28, 2019

I'm still trying to understand the project structure as a whole, but I imagine something like that might work:

    if (!api.service.projectOptions.keepVueInstance) {
      // externalize Vue in case user imports it
      config
        .externals({
          ...config.get('externals'),
          vue: {
            commonjs: 'vue',
            commonjs2: 'vue',
            root: 'Vue'
          }
        })
    }

Here in the original file:

But I'm not sure how to create a test to it right now, still searching some examples in the project

@ghost
Copy link
Author

ghost commented May 31, 2019

Looking at the code snippet you provided, I might suggest a slightly different incarnation of it. That approach has a limitation in that if your "keepVueInstance" is false, then externals that the developer wanted to configure will not be applied either.

Maybe something like the following:

// externalize Vue in case user imports it

config.externals({
     ...config.get('externals'),
     ...(!api.service.projectOptions.keepVueInstance ? { 
          vue: {
               commonjs: 'vue',
               commonjs2: 'vue',
               root: 'Vue'
          }
     } : {})
   })

@trickstival
Copy link
Contributor

That's actually much better!

@ghost
Copy link
Author

ghost commented May 31, 2019

Apologies for the formatting, just fixed it. I am still learning my way around GitHub's formatting features.

@trickstival
Copy link
Contributor

[OFFTOPIC]

If you add js after your backticks you get some code highlighting. Like that:
` ``js
let a = 'hey'

`` `
Without spaces:

let a = 'hey'

@mithom
Copy link

mithom commented Jun 12, 2019

i am trying to do something very similar (a core app with modules the user can install, but i don't want to update the app when new modules become available). I justed wanted to start looking into the lib or wc option when i tumbled upon this. If you want to load them at runtime, won't the webcomponent build be an option? or does the webcomponent solution not offer the following capabilities:

<component :is="moduleA">slot content</component>

@romansp
Copy link
Contributor

romansp commented Jul 9, 2019

I'm trying to do this exact thing. Is there any workaround? Also, I wonder if this issue is up for grabs, I would like to work on it.

romansp pushed a commit to romansp/vue-cli that referenced this issue Jul 10, 2019
…tion of Vue when build target is Lib.

Resolves vuejs#4055.
romansp added a commit to romansp/vue-cli that referenced this issue Jul 10, 2019
@haoqunjiang
Copy link
Member

I'm skeptical about the actual use case.
But if we have to support it, I think vue.config.js is not the best place to put this option, as it only applies the lib or web component target. This name also leads to confusion (Vue instance typically refers to the result of new Vue).

What about adding a flag to the build command? Like:

--inline-vue         include the Vue module in the final bundle of library or web component target

@mithom
Copy link

mithom commented Aug 13, 2019

I got my plan to work by globally registering the components i wanted to share to the subcomponents. This way i don't have to call anything special. For data transfer between both i use either props or vuex. I build with target lib and include them using dynamic imports with the native require instead of webpack require.

So far no issues for me

@agileago
Copy link

@sodatea When will it be released? i strongly need this feature

@agileago
Copy link

@mithom how do you resolve this question? is there some code to see ?

@romansp
Copy link
Contributor

romansp commented Aug 15, 2019

@sodatea, I really like flag for build command more than vue.config.js option.

Worth updating #4261 PR?

@haoqunjiang
Copy link
Member

@romansp Yeah go ahead please.

romansp added a commit to romansp/vue-cli that referenced this issue Aug 16, 2019
romansp added a commit to romansp/vue-cli that referenced this issue Aug 16, 2019
…rnalization of Vue when build target is Lib.

Resolves vuejs#4055.
romansp added a commit to romansp/vue-cli that referenced this issue Aug 16, 2019
…ernalization of Vue when build target is Lib.

Resolves vuejs#4055.
romansp added a commit to romansp/vue-cli that referenced this issue Aug 16, 2019
…ernalization of Vue when build target is Lib.Resolves vuejs#4055.
@romansp
Copy link
Contributor

romansp commented Aug 16, 2019

@sodatea I updated #4261 PR. I think we can continue discussion over there.

@agileago
Copy link

@sodatea
Is it possible to merge and publish as soon as possible?

haoqunjiang pushed a commit that referenced this issue Aug 19, 2019
haoqunjiang pushed a commit that referenced this issue Aug 21, 2019
…ation of Vue (#4261)

Resolves #4055.

(cherry picked from commit 86f4f5f)
@haoqunjiang
Copy link
Member

This feature is now shipped in both v3.11.0 & v4.0.0-rc.0

@agileago
Copy link

@sodatea thanks. perfect!

@dikaso
Copy link

dikaso commented Nov 5, 2019

When inline flag is true, is Vue attached to global variable?

What if two components bundle different versions of Vue?

@agileago
Copy link

agileago commented Nov 6, 2019

@Dika-pro no. Vue is module

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants