来自 ElementUI 的 VueJs + Webpack 延迟加载模块

VueJs + Webpack lazyload modules from ElementUI

我想在 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 元素(而不是整个库)?

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

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

Can I import only individual elements from ElementUI?

ElementUI docs recommend using 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);
    

Can I dynamically import individual elements?

是的,有可能。

首先,了解 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__.babelrc.
  • 内的Babel预设选项中配置
  • 转换包括将组件名称 (__ComponentName__) 格式化为 kebab-case (__component-name__)。例如,Button 变为 buttonDatePicker 变成 date-picker.
  • 确保删除现有的 ElementUI 导入,这会破坏 "on demand" 导入:

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

例如,要使用 Chalk 主题导入 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>

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