VueJs + Webpack lazyload modules from ElementUI

巧了我就是萌 提交于 2020-12-29 06:41:36

问题


I would like to lazy-load a specific element of ElementUI in a Vue component.

I tried this:

import { Tree } from /* webpackChunkName : "element-ui" */ 'element-ui';

Vue.component(Tree.name, Tree);
Vue.use(Tree);

And this:

{
  components: {
    'el-tree': () => import(/* webpackChunkName : "element-ui" */ "element-ui").then(({Tree}) => Tree)
  }
}

But in both cases, the element-ui.js chunk file is not created, and the full library is inserted into the main.js file instead.

How do I dynamically import only the used elements of ElementUI (not the entire library)?


回答1:


Why does import('element-ui').then(({Tree}) => Tree) bundle the whole ElementUI library?

The element-ui library is a CommonJS module, which is not tree-shakeable (webpack-common-shake exists, but your mileage may vary).

Can I import only individual elements from ElementUI?

The ElementUI docs recommend using babel-plugin-component (also written by ElementUI) to import only the elements used. The usage is documented as follows:

  1. Install babel-plugin-component:

    npm install babel-plugin-component -D
    
  2. Edit .babelrc to include:

    {
      "presets": [["es2015", { "modules": false }]],
      "plugins": [
        [
          "component",
          {
            "libraryName": "element-ui",
            "styleLibraryName": "theme-chalk"
          }
        ]
      ]
    }
    
  3. Statically import the desired element, and initialize it as a Vue component:

    import { Button } from 'element-ui';
    Vue.component(Button.name, Button);
    

Can I dynamically import individual elements?

Yes, it's possible.

First, it's useful to understand how babel-plugin-component works. The plugin effectively converts this:

import { __ComponentName__ } from 'element-ui';
Vue.component('x-foo', __ComponentName__);

into:

import __ComponentName__ from 'element-ui/lib/__component-name__';
import 'element-ui/lib/__styleLibraryName__/__component-name__.css';
Vue.component('x-foo', __ComponentName__);

Notes:

  • __styleLibraryName__ is configured in the Babel preset options within .babelrc.
  • The conversion includes formatting the component's name (__ComponentName__) in kebab-case (__component-name__). For example, Button becomes button; and DatePicker becomes date-picker.
  • Make sure to remove existing ElementUI imports, which would defeat the "on demand" imports:

    // import ElementUI from 'element-ui'; // REMOVE
    // import 'element-ui/lib/theme-chalk/index.css'; // REMOVE
    

So, we can use that knowledge to dynamically import a specific element like this:

// main.js
import 'element-ui/lib/__styleLibraryName__/__component-name__.css';
Vue.component('x-foo', () => import(/* webpackChunkName: "x-foo" */ 'element-ui/lib/__component-name__'));

Or:

<!-- MyComponent.vue -->
<script>
import 'element-ui/lib/__styleLibraryName__/__component-name__.css';

export default {
  components: {
    'x-foo': () => import(/* webpackChunkName: "x-foo" */ 'element-ui/lib/__component-name__'),
  }
}
</script>

For example, to import Button with the Chalk theme:

<!-- MyComponent.vue -->
<script>
import 'element-ui/lib/theme-chalk/button.css';

export default {
  components: {
    'el-button': () => import(/* webpackChunkName: "element-button" */ 'element-ui/lib/button'),
  }
}
</script>

However, these elements are relatively small and thus probably not worth lazy-loading, considering the overhead of the network requests for the container chunk plus the element chunk. On the other hand, the savings might be worthwhile if the elements were conditionally rendered and that condition were rarely true.



来源:https://stackoverflow.com/questions/52104217/vuejs-webpack-lazyload-modules-from-elementui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!