Skip to content

How can we load Vue once and only if needed on pages with multiple javascript 'bundles'?

Our pattern of including separate javascript 'bundles' as page_specific_javascripts for large vue-based 'applications' allows us to require vue only on pages where it will be used.

But I'm encountering a problem with this on the merge request page, where as many as 3 app bundles may be loaded at a time, (diff_notes_bundle, issuable_bundle, and the widget_bundle) each of which requires Vue. Sprockets is not smart enough to only include Vue once, which results in loading multiple copies of Vue.

This is not only a performance problem, it blocks development because as each copy of Vue is loaded and registered to, it is then clobbered by the next copy, leading to hard-to-debug Did you correctly register X-component? messages from Vue.

When I was working on timetracking, we solved this problem by simply removing the require statement from one of the bundles. But now that I'm working on a separate bundle for the merge request widget, I'm realizing that's not a viable solution any longer because:

  1. These 3 'apps' are not all loaded on version of MR pages. This can be a result of user settings, MR state, or whether the GitLab instance is EE or CE. Thus, it is not possible to choose a bundle to be responsible for loading Vue, and remove other require statements.
  2. We make use of reusable Vue-based components in some of these. These components depend on Vue and must be loaded after it. So, even if we load Vue from a single source for each page, the components need to declare their dependency on Vue.

I'm not really sure where to go with this. Am I missing something obvious? Our transition to webpack will likely solve the problem, but in the meantime, I'm blocked. Anyone have ideas for a stopgap solution here?

cc: @mikegreiling @fatihacet @jschatz1