来自ElementUI的VueJs + Webpack lazyload模块

Pet*_*sko 4 lazy-loading webpack vue.js vuejs2

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

我试过这个:

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

Vue.component(Tree.name, Tree);
Vue.use(Tree);
Run Code Online (Sandbox Code Playgroud)

还有这个:

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

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

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

ton*_*y19 15

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

element-ui 库是一个CommonJS模块,它不是树可以摇动的(webpack-common-shake存在,但你的里程可能会有所不同).

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

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

  1. 安装babel-plugin-component:

    npm install babel-plugin-component -D
    
    Run Code Online (Sandbox Code Playgroud)
  2. 编辑.babelrc包括:

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

    import { Button } from 'element-ui';
    Vue.component(Button.name, Button);
    
    Run Code Online (Sandbox Code Playgroud)

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

是的,这是可能的.

首先,了解babel-plugin-component工作原理是有用的.该插件有效地转换了这个:

import { __ComponentName__ } from 'element-ui';
Vue.component('x-foo', __ComponentName__);
Run Code Online (Sandbox Code Playgroud)

成:

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

笔记:

  • __styleLibraryName__在Babel预设选项中配置.babelrc.
  • 转换包括__ComponentName__在kebab-case(__component-name__)中格式化组件的名称().例如,Button成为button; 并DatePicker成为date-picker.
  • 确保删除现有的ElementUI导入,这将导致"按需"导入失败:

    // import ElementUI from 'element-ui'; // REMOVE
    // import 'element-ui/lib/theme-chalk/index.css'; // REMOVE
    
    Run Code Online (Sandbox Code Playgroud)

因此,我们可以使用该知识动态导入特定元素,如下所示:

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

要么:

<!-- 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>
Run Code Online (Sandbox Code Playgroud)

例如,要Button使用Chalk主题导入:

<!-- 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>
Run Code Online (Sandbox Code Playgroud)

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

  • 天哪,这个答案很有帮助。 (3认同)