Skip to content

[Vue] Allow passing multiple contexts #461

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

Open
wants to merge 2 commits into
base: 2.x
Choose a base branch
from

Conversation

MantraMediaMike
Copy link

Q A
Bug fix? no
New feature? no
License MIT

Currently only one context can be passed and registered.

This way it is not possible to use proper code splitting and the generated Javascript will always contain all Vue components though they might not be needed on the page displayed.

Also in the current version the context is passed with deep: true but this is not used, the component name needs to be passed with the sub directory as a prefix.

This pull requests allows either passing the context as a string

registerVueControllerComponents(require.context('./vue/controllers/', true, /\.vue$/))

or as an array

registerVueControllerComponents([
        require.context('./vue/controllers/common', true, /\.vue$/),
        require.context('./vue/controllers/profile/', true, /\.vue$/),
        require.context('./vue/controllers/search/', true, /\.vue$/)
]);

Currently only one context is allowed. This way the generated Javascript always includes every Vue component and it is not possible to do proper code splitting.
Copy link
Member

@weaverryan weaverryan left a comment

Choose a reason for hiding this comment

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

thanks for getting this rolling 👍

@@ -9,18 +9,21 @@

'use strict';

export function registerVueControllerComponents(context: __WebpackModuleApi.RequireContext) {
export function registerVueControllerComponents(contexts: any) {
Copy link
Member

Choose a reason for hiding this comment

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

Could we:

Suggested change
export function registerVueControllerComponents(contexts: any) {
export function registerVueControllerComponents(context: __WebpackModuleApi.RequireContext|Array< __WebpackModuleApi.RequireContext >) {

const component = vueControllers[`./${name}.vue`];
const component = Object.values(
Object.fromEntries(Object.entries(vueControllers).filter(([key]) => key.endsWith(`${name}.vue`)))
)[0];
Copy link
Member

Choose a reason for hiding this comment

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

tbh, this makes my head spin a little bit.

If I import 2 contexts, and each contains a Hello.vue, the 2nd one will "win" over the first, correct?

With the new code, is the "key" inside vueControllers now a longer path (e.g. common/Hello.vue instead of just Hello.vue)? What makes these code changes needed?

Copy link
Author

@MantraMediaMike MantraMediaMike Sep 20, 2022

Choose a reason for hiding this comment

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

This would then not be possible or just very hacky with the way require context works.

I personally think that a project should never have 2 components with the same name and that the component names should always be very explicit and never as generic as just Menu. (https://vuejs.org/style-guide/rules-essential.html)

But if this should be possible, I think we can close the pull request for now?

@weaverryan
Copy link
Member

@MantraMediaMike

But if this should be possible, I think we can close the pull request for now?

Can you explain the problem to me a bit more? What exactly is the problem with require.context that means we should close this PR? Thanks :)

@MantraMediaMike
Copy link
Author

MantraMediaMike commented Sep 20, 2022

Can you explain the problem to me a bit more? What exactly is the problem with require.context that means we should close this PR? Thanks :)

Wow, that was a fast reply :) I moved the other reply to the comments while you were replying, sorry for this.

The keys function of require.context returns the components scoped to the path eg ./HeaderMenu.vue and not including the path.

One hacky way I can think of is using default.__file which has the full path to the component

            const component = r(key).default.__file
            vueControllers[component] = r(key).default

but I think the __file property is not exposed by the Typescript interface so would fail in the test

Or passing the contexts in a more explicit way

{
        header: require.context('./vue/controllers/header', true, /\.vue$/),
        search: require.context('./vue/controllers/search', true, /\.vue$/)
}

and then using the object key to generate the component entry.

But this all does not feel clean to me.

@weaverryan
Copy link
Member

That's an excellent clarification!

I am ok with the fact that we only have access to the short name - e.g. Hello.vue. If you decide to import from 2 different contexts, and you have a Hello.vue from both, then that's your mistake (in probably the 2nd one would take precedence over the first). WDYT?

@MantraMediaMike
Copy link
Author

MantraMediaMike commented Sep 26, 2022

I think the behavior you describe is the expected one as right now this is already not possible in a non-ux approach without aliasing an import of the component and using different html tags.

If the script detects more than one component I would throw an error that more than one component with the same name was found.

Unfortunately I am very busy until next week so can not send an updated commit yet.

@weaverryan
Copy link
Member

If the script detects more than one component I would throw an error that more than one component with the same name was found.

That sounds very reasonable 👍

Unfortunately I am very busy until next week so can not send an updated commit yet.

No worries, I look forward to when you have some time :). #482 will likely be merged soon, which will require some changes to your PR. A lot of code changes in #482, but I still think multiple contexts will work fine with those changes.

Cheers!

@Gus-25
Copy link

Gus-25 commented Jan 5, 2024

Hello !
I recently installed symfony ux vue in one of my company project, it is working fine (and it is amazing by the way) but i need to register vue components from different bundles.

Is this PR still relevant today?

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

Successfully merging this pull request may close these issues.

4 participants