Загрузка библиотек компонентов по требованию

JavaScript

Загрузка библиотек компонентов по требованию

Способ

В настоящее время существует два способа реализации загрузки по требованию.

  • использоватьbabel-plugin-importПлагины для автоматического импорта по запросу
  • поставкаes moduleверсия, наtree shaking

babel-plugin-import

babel-plugin-importдаant-designПлагин babel, разработанный командой, в основном используется для загрузки модулей по запросу. Принцип заключается в прохождении метода прямого введения черезbabelПреобразовано в введение по требованию. Если CSS также необходимо загрузить по запросу, также вводится код ссылки CSS.

Например:

import { Button } from 'antd';

Перевести в:

import Button from 'antd/es/button';
import 'antd/es/button/style';

babel-plugin-importПо умолчаниюjsпуть[libraryName]/[moduleType]/[componentName],По умолчанию样式путь[libraryName]/[moduleType]/[componentName]/style, если используемая библиотека компонентов пользовательского интерфейса не соответствуетbabel-plugin-importПравила преобразования для , могут быть выполнены с помощьюbabel-plugin-importкоторый предоставилcustomNameполе для настройки преобразованного пути. пройти черезstyleполя для дальнейшей настройки преобразованного样式дорожка.

Документы по специальному использованию см.babel-plugin-import

tree shaking

Если библиотека компонентов предоставляетes moduleверсию и включитьtree shaking, то не надоbabel-plugin-importВы также можете достичь цели нагрузки по требованию, этот метод только для вjs, для样式Загрузку по требованию по-прежнему необходимо вводить вручную. Конечноbabel-plugin-importа такжеtree shakingТакже можно использовать одновременно. Однако в большинстве случаев между сосуществованием и одноразовым использованием нет большого разрыва.

Например:

import { Button } from 'antd';
import 'antd/es/button/style';

webpackсквозьpackage.jsonнастраиватьsideEffects: false, включиtree shaking.

Какое приложение ssr использовать?

дляcsrизspaПроекты, использующие два вышеуказанных метода для достижения того же эффекта. Но если наш проектssrприложение, может быть небольшая разница, потому чтоssrиспользуется дляserverсторону, мы устанавливаемwebpack.server.config.jsизexternal, сторонний модуль не будет переданwebpackупаковка, прямойrequireЕго можно ввести, цель этого не надеятьсяserverконецwebpackупакованныйbundleРазмер файла слишком велик.

// webpack.server.config.js
module.exports = {
    ...
    externals: nodeExternals({
    whitelist: [/\.(css|scss|less)$/, /\?vue&type=style/] //除去样式
  }),
}

если мы используемtree shakingпуть, потому чтоserverконецwebpackНе разобравшись с этими сторонними модулями, то никак не обойтисьtree shaking,а такжеserverконецnodeсреда, в настоящее времяnodeправильноesmПоддержка не очень хорошая, поэтому она все еще широко используетсяcjs. затем вserverС другой стороны, библиотека компонентов фактически будет импортирована целиком.

Итак, если вам нужноserverРекомендуется использовать загрузку по требованию на терминалеbabel-plugin-import.

Теперь я будуbootstrap-vueНапример, потому чтоbootstrap-vueиспользоватьbabel-plugin-importНе очень гладко.

bootstrap-vue

bootstrap-vue предоставляетes moduleверсию и включитьtree shaking, может и не понадобитсяbabel-plugin-import. Импорт напрямую.

//...引入样式
import { ButtonPlugin, LayoutPlugin, TabsPlugin } from 'bootstrap-vue'
Vue.use(ButtonPlugin)
Vue.use(LayoutPlugin)
Vue.use(TabsPlugin)

но если вssrВ заявлении по причинам, указанным выше,serverПо сути, введениеdist/bootstrap-vue.common.js, мы можем пройтиalinodeиз堆快照Инструмент анализа, чтобы увидеть, сколько памяти занимает этот файл.

можно увидетьbootstrap-vueизRetained HeapДостиг1.18MB, занимает первое место. Итак, если вы хотитеserverконецbootstrap-vueТакже выполните загрузку по требованию, вы можете использоватьbabel-plugin-import.

Использование babel-plugin-import

bootstrap-vueразделен наcomponents,directives, два компонента, то есть компоненты и инструкции, и обеспечивает два метода введения, один из которых заключается в регистрации компонентов или инструкций в пакетахplugin, а другой - вводить компоненты или директивы по отдельности. Например:

//批量注册组件
import { LayoutPlugin } from 'bootstrap-vue'
Vue.use(LayoutPlugin)
//批量注册指令
import { VBModalPlugin } from 'bootstrap-vue'
Vue.use(VBModalPlugin)
//单独注册组件
import { BModal } from 'bootstrap-vue'
Vue.compoents('b-modal', BModal)
//单独注册插件
import { VBModal } from 'bootstrap-vue'
Vue.directives('b-modal', VBModal)

bootstrap-vueкаталог не соответствуетbabel-plugin-importправила преобразования, потому чтоbootstrap-vueНе только предоставляет две основные папкиcomponents,directives, но и подключаемые компоненты, а также компоненты, не являющиеся подключаемыми модулями. Кроме того, каталог компонентов также включает несколько компонентов. Такие какcarouselЭтот каталог содержитcarouselа такжеcarousel-slideдва компонента.

Ввиду описанной выше ситуации нам необходимо настроить путь конверсии, используяbabel-plugin-importизcustomName,styleполе. Мы можем использовать их для настройки функции преобразования для реализации следующих правил преобразования.bootstrap-vueне предоставленstyleЗагрузка по запросу, поэтому загрузка по запросу здесь только дляjs.

import { LayoutPlugin,VBModalPlugin,Carousel,CarouselSlide } from 'bootstrap-vue'
=> 
//组件插件
import LayoutPlugin from 'bootstrap-vue/esm/components/layout/index.js'
//指令插件
import VBModalPlugin from 'bootstrap-vue/esm/directives/modal/index.js'
//单独引入
import Carousel from 'bootstrap-vue/esm/components/carousel/carousel.js'
//CarouselSlide包含在carousel文件夹里
import CarouselSlide from 'bootstrap-vue/esm/components/carousel/carousel-slide.js'

Из вышеизложенного мы можем найти:

  • кVBЭто начинается сdirective, кBЭто начинается сcomponent.
  • кPluginвсе заканчиваетсяplugin,НетPluginПервые регистрируются индивидуально.
  • Если это отдельно импортируемый компонент, вам необходимо получить каталог его компонентов.

Итак, наш финал.babelrc.jsдолжно быть написано так

//提供bootstrap的所有组件目录
const bootstrapComponents = [
    'alert',
    'badge',
    'breadcrumb',
    'button',
    'button-group',
    'button-toolbar',
    'card',
    'carousel',
    'collapse',
    'dropdown',
    'embed',
    'form',
    'form-checkbox',
    'form-file',
    'form-group',
    'form-input',
    'form-radio',
    'form-select',
    'form-textarea',
    'image',
    'input-group',
    'jumbotron',
    'layout',
    'link',
    'list-group',
    'media',
    'modal',
    'nav',
    'navbar',
    'pagination',
    'pagination-nav',
    'popover',
    'progress',
    'spinner',
    'table',
    'tabs',
    'toast',
    'tooltip'
  ]
module.exports = {
  ...
  'plugins': [
    [
      'import',
      {
        'libraryName': 'bootstrap-vue',
        camel2DashComponentName: false // 关闭驼峰转换
        'customName': (name) => {
          let category, cname = name, isPlugin = false
          if (/^VB/.test(cname)) { //directives like VBModalPlugin, VBModal
            category = 'directives'
            cname = cname.replace(/^VB/, '')
          } else { // components
            category = 'components'
          }
          if (/Plugin$/.test(cname)) { //plugin like ButtonPlugin,ModalPlugin
            isPlugin = true
            cname = `${cname.replace(/Plugin$/, '')}`
          } else { //Individual components like BButton, BModal
            cname = cname.replace(/^B/, '')
          }
          //FormCheckbox -> form-checkbox
          cname = cname.replace(/\B([A-Z])/, (m) => {
            return `-${m}`
          }).toLowerCase()
          // 这里需要处理下当一个组件文件夹里包含多个组件的时候,如: carousel-slide -> /carousel/carousel-slide 
           if (!isPlugin && category === 'components') {
            let dir = bootstrapComponents.filter(c => {
              return cname.startsWith(c)
            })[0]
            return `bootstrap-vue/${process.env.VUE_ENV === 'server' ? 'es' : 'esm'}/${category}/${dir}/${cname}`
          }
          return `bootstrap-vue/${process.env.VUE_ENV === 'server' ? 'es' : 'esm'}/${category}/${cname}`
        }
      }
    ]
  ]
}

process.env.VUE_ENVпеременная окружения, введенная для различенияserverконец илиclientконец. здесь, еслиserverконечное применениеcjs,bootstrap-vueизesФактическиcjs,еслиclient, затем используйтеesm.

Суммировать

Распространенные методы загрузки по запросу

  • использоватьbabel-plugin-importплагин
  • поставкаes moduleверсия, наtree shaking

babel-plugin-importПлагины могут реализоватьjs,cssЗагрузка по требованию, по существу按需引入способ изменить на直接引入Путь. Если настроеноstyleполе, а также инжектируетstyleкод прямого импорта.

tree shakingтолько дляjs,cssЕсли его необходимо загрузить по запросу, его необходимо импортировать вручную.

Напротив, посколькуtree shakingтолько дляjs,babel-plugin-importбыло бы удобнее.babel-plugin-importа такжеtree shakingТакже можно использовать одновременно. Параллельное использование В некоторых случаях объем будет относительно небольшим, но он не сильно отличается от объема, используемого отдельно.

ssrприложение, так какserverконецwebpackне будет работать со сторонними модулями, так что нет возможностиtree shaking,еслиserverКлиент также должен учитывать загрузку по требованию, вы можете использоватьbabel-plugin-import.

Если используемая библиотека компонентов пользовательского интерфейса не соответствуетbabel-plugin-importПравила преобразования для , могут быть выполнены с помощьюbabel-plugin-importкоторый предоставилcustomNameполе для настройки преобразованного пути. пройти черезstyleполя для дальнейшей настройки преобразованногоstyleдорожка.