3

Problem: In my vue-cli 4 app, I'd like to have build: script, which generates production bundle, with specific .vue-components not being included in some cases. In other cases they should be included. Also, these components are stored in app itself - not in external library.

I've tried: to import .vue-components dynamically - let's say I have an array:

const customPreset = ['WidgetFirst', 'WidgetSecond', ...]

And empty object:

const widgets = {}

So I've tried to make something like this:

customPreset.forEach(v => { Object.assign(widgets, { [v]: () => import('./' + v + '.vue') }) })
export default widgets

Changing customPreset to some other array would allow to import another set of components...

But that doesn't work, because import() cannot operate with expressions.

So, what could be done to include various .vue-components into production bundle in various cases? Maybe it could be achieved through tweaking vue.config.js?

KrasnokutskiyEA
  • 587
  • 1
  • 6
  • 20

1 Answers1

0

What you are looking for is lazy loaded components. In Vue they are available at multiple points.

  1. In vue-router - you can import components per route, to load only when they are needed:

This is how to define an async component that will be automatically code-split by webpack:

const Foo = () => import('./Foo.vue')

You can also group components in the same chunk:

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
  1. Second option is Dynamic/Async components, which can be used in .vue files like this:
Vue.component(
  'async-webpack-example',
  // The `import` function returns a Promise.
  () => import('./my-async-component')
)

It even support loading state, straight from the box:

const AsyncComponent = () => ({
  // The component to load (should be a Promise)
  component: import('./MyComponent.vue'),
  // A component to use while the async component is loading
  loading: LoadingComponent,
  // A component to use if the load fails
  error: ErrorComponent,
  // Delay before showing the loading component. Default: 200ms.
  delay: 200,
  // The error component will be displayed if a timeout is
  // provided and exceeded. Default: Infinity.
  timeout: 3000
})
tony19
  • 125,647
  • 18
  • 229
  • 307
Alex Brohshtut
  • 2,050
  • 12
  • 13
  • 1
    Thanks for answer! Unfortunately, this doesn't work for me. I'm using 2nd option, as there's no router in project. On local development this approach works fine, but when I'm exploring my production bundle contents with webpackBundleAnalyzer (after npm run build) - i still see all components, including those, which were not supposed to be included. It even seems like webpack puts .vue component into production bundle if it comes across import declaration in src code. – KrasnokutskiyEA Apr 02 '20 at 10:21
  • 1
    Did you try to add /* webpackChunkName: "group-foo" */ in component as well? – Alex Brohshtut Apr 02 '20 at 10:26
  • 1
    I'm importing component like this: Widget: () => import(/* webpackChunkName: "Widget" */ './Widget.vue') Even if i try to import it conditionally - it somehow gets iincluded into production bundle... – KrasnokutskiyEA Apr 02 '20 at 10:39
  • 1
    Well, you will see all components in a bundle analyzer, they are just not loaded together. But they exists in different files in bundles. Like chunk.0.js – Alex Brohshtut Apr 02 '20 at 10:46
  • 1
    Yes, but I'd like to completely exclude some .vue-components from production .js bundle. My app comes to various clients with various configurations: some clients need to have one combination of widgets (.vue-components), while other clients don't need to have some of these widgets in their app copy. Of course, I can manually delete specific widgets (chunks) from dist folder, but there should be a better way of customizing the app... – KrasnokutskiyEA Apr 02 '20 at 10:54
  • 1
    Got it, then probably you need to move towards different webpack configs.. – Alex Brohshtut Apr 02 '20 at 11:40
  • I'm now digging into webpack IgnorePlugin and also thinking about modifying ./src folder somehow just before npm run build to prevent webpack from processing specific .vue-files – KrasnokutskiyEA Apr 02 '20 at 11:45