ElementUI的VueJs + Webpack延迟加载模块

时间:2018-08-30 19:34:57

标签: vue.js webpack vuejs2 lazy-loading

我想在Vue组件中延迟加载ElementUI的特定元素。

我尝试过:

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

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

这:

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

但是在两种情况下,都不会创建element-ui.js块文件,而是将完整的库插入main.js文件中。

如何仅动态导入ElementUI的已使用元素(而不是整个库)?

1 个答案:

答案 0 :(得分:7)

  

为什么import('element-ui').then(({Tree}) => Tree)会捆绑整个ElementUI库?

不可摇晃的element-ui library is a CommonJS module(存在webpack-common-shake,但里程可能会有所不同)。

  

我只能从ElementUI导入单个元素吗?

ElementUI docs建议使用babel-plugin-component(也由ElementUI编写)来仅导入使用的元素。用法记录如下:

  1. 安装babel-plugin-component

     npm install babel-plugin-component -D
    
  2. 编辑.babelrc以包括:

    {
      "presets": [["es2015", { "modules": false }]],
      "plugins": [
        [
          "component",
          {
            "libraryName": "element-ui",
            "styleLibraryName": "theme-chalk"
          }
        ]
      ]
    }
    
  3. 静态导入所需元素,并将其初始化为Vue组件:

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

我可以动态导入单个元素吗?

是的,有可能。

首先,了解babel-plugin-component的工作方式很有用。该插件可以有效地进行以下转换:

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

进入:

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

注释:

    __styleLibraryName__的Babel预设选项中配置
  • .babelrc
  • 转换包括以kebab-case(__ComponentName__)格式设置组件名称(__component-name__)。例如,Button变成button;并且DatePicker变成date-picker
  • 确保删除现有的ElementUI导入,这将破坏“按需”导入:

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

因此,我们可以使用这些知识来动态导入特定的元素,例如:

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

或者:

// 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>

例如,要导入带有{粉笔}主题的Button

// 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>

但是,考虑到对容器块加上元素块的网络请求的开销,这些元素相对较小,因此可能不值得延迟加载。另一方面,如果有条件地渲染元素并且这种条件很少为真,那么节省可能是值得的。