VueJs + Webpack ленивые модули от ElementUI - PullRequest
0 голосов
/ 30 августа 2018

Я бы хотел лениво загрузить определенный элемент ElementUI в компонент Vue.

Я пробовал это:

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 голосов
/ 31 августа 2018

Почему import('element-ui').then(({Tree}) => Tree) связывает всю библиотеку ElementUI?

Библиотека element-ui является модулем CommonJS , который нельзя расшатывать по дереву (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.
  • Преобразование включает в себя форматирование имени компонента (__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 с темой 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>

Однако эти элементы относительно малы и, следовательно, вероятно, не стоят ленивой загрузки, учитывая накладные расходы сетевых запросов для порции контейнера плюс порция элемента. С другой стороны, экономия может быть целесообразной, если элементы были отображены условно, и это условие редко выполнялось.

...