# Однофайловые компоненты

# Введение

Во многих проектах, глобальные компоненты определяются посредством app.component, с последующим app.mount('#app') для указания элемента-контейнера в теле каждой страницы.

Для проектов малого и среднего размера, в которых JavaScript используется лишь для некоторых страниц, этот подход может прекрасно работать. В более же сложных проектах или в случаях, когда весь ваш фронтенд управляется JavaScript, явными становятся следующие недостатки:

  • Глобальное определение заставляет давать уникальное имя каждому компоненту
  • Строковым шаблонам не хватает подсветки синтаксиса. Кроме того, приходится использовать уродливые слэши для многострочного HTML.
  • Нет модульной поддержки CSS — в то время как HTML и JavaScript разбиваются на модули-компоненты, CSS оказывается за бортом.
  • Отсутствие шага сборки ограничивает нас только HTML и ES5 JavaScript, не позволяя использовать препроцессоры вроде Pug (бывший Jade) и Babel

Все эти недостатки решаются однофайловыми компонентами с расширением .vue, использование которых позволяют такие инструменты как Webpack и Browserify.

Вот простой пример файла, который мы назовём Hello.vue:

Single-file component example (click for code as text)

Мы получили:

Как и обещалось, мы также можем использовать препроцессоры, такие как Pug, Babel (с модулями ES2015) и Stylus для создания более ясных и функциональных компонентов.

Single-file component with pre-processors example (click for code as text)

Перечисленные языки даны только для примера. С тем же успехом можно использовать TypeScript, SCSS, PostCSS, или любые другие пре- или постпроцессоры по вкусу. При использовании Webpack вместе с vue-loader, вы также получаете прекрасную поддержку CSS-модулей.

# Что насчёт разделения ответственности?

Одна важная вещь, что следует отметить — разделение ответственности это не то же самое, что разделение на файлы по типу. В современной разработке UI мы обнаружили, что вместо разделения кодовой базы на три огромных слоя, что тесно переплетаются друг с другом, имеет больше смысла делить их на слабо связанные компоненты и компоновать уже их. Внутри компонента, его шаблон, логика и стили неразрывно связаны между собой, что позволяет сделать компонент более сплочённым и удобным в поддержке.

Если вам не нравится идея однофайловых компонентов, вы также можете пользоваться возможностями горячей замены модулей и прекомпиляцией, выделив JavaScript и CSS в отдельные файлы:

<!-- my-component.vue -->
<template>
  <div>Это будет предварительно скомпилировано</div>
</template>
<script src="./my-component.js"></script>
<style src="./my-component.css"></style>
1
2
3
4
5
6

# Начало работы

# Песочница с примером

Если вы хотите прямо сейчас поиграть с однофайловыми компонентами — начните с этого простого todo приложения (opens new window) на CodeSandbox.

# Для новичков в модульных системах сборки JavaScript

С .vue-компонентами, мы входим во вселенную продвинутых JavaScript-приложений. Это значит, что если вы этого ещё не сделали, нужно будет освоить некоторые дополнительные инструменты:

После того как вы уделили время этим ресурсам, мы советуем вам посмотреть на Vue CLI (opens new window). Следуйте инструкциям, и очень скоро у вас будет рабочий проект с .vue-компонентами, ES2015, webpack и горячей перезагрузкой модулей.

# Для продвинутых пользователей

CLI позаботится о большинстве настроек конфигурации сборки для вас, но при необходимости позволяет настроить любые детали через опции конфигурации (opens new window).

Если вы предпочитаете создавать конфигурацию сборки с нуля, то необходимо вручную настроить webpack для работы с vue-loader (opens new window). Чтобы узнать больше о webpack, обратитесь к его официальной документации (opens new window) и webpack learning academy (opens new window).

# Сборка с Rollup

Большая часть времени разработки сторонней библиотеки уходит на то, чтобы позволить пользователям библиотеки использовать преимущества tree shaking (opens new window). Для поддержки tree-shaking требуется сборка в виде esm модуля. Поскольку webpack и, соответственно, vue-cli не поддерживают сборку esm модулей, потребуется использовать Rollup (opens new window).

# Установка Rollup

Необходимо установить Rollup и несколько зависимостей:

npm install --save-dev rollup @rollup/plugin-commonjs rollup-plugin-vue
1

Это минимальный набор плагинов rollup, которые нужны для компиляции esm модулей. Также можно добавить rollup-plugin-babel (opens new window) для транспиляции кода и node-resolve (opens new window), если используем зависимости, которые должны поставляться в итоговой сборке библиотеки.

# Конфигурирование Rollup

Для конфигурации сборки с Rollup нужно создать файл rollup.config.js в корне проекта:

touch rollup.config.js
1

После создания файла нужно открыть его в любом редакторе и добавить следующий код:

// импорт используемых сторонних плагинов
import commonjs from 'rollup-plugin-commonjs'
import VuePlugin from 'rollup-plugin-vue'
import pkg from './package.json' // импорт package.json для переиспользования имени

export default {
  // этот файл будет содержать все экспортируемые компоненты/функции
  input: 'src/index.js',
  // это массив выходных форматов
  output: [
    {
      file: pkg.module, // название создаваемой esm библиотеки
      format: 'esm', // выбранный формат
      sourcemap: true, // флаг rollup для добавления sourcemaps
    }
  ],
  // это массив плагинов, которые требуется включить
  plugins: [
    commonjs(),
    VuePlugin()
  ],
  // просим rollup не включать в сборку библиотеки Vue
  external: ['vue']
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# Конфигурирование package.json

Чтобы воспользоваться только что созданным esm модулем нужно добавить несколько полей в файл package.json:

 "scripts": {
   ...
   "build": "rollup -c rollup.config.js",
   ...
 },
 "module": "dist/my-library-name.esm.js",
 "files": [
   "dist/",
 ],
1
2
3
4
5
6
7
8
9

Здесь мы уточняем следующее:

  • каким образом собирать пакет
  • какие файлы хотим упаковать в пакет
  • какой файл будет esm модулем

# Сборка umd и cjs модулей

Чтобы одновременно собирать и umd и cjs модули, достаточно добавить несколько строк конфигурации в rollup.config.js и package.json

# rollup.config.js
output: [
  ...
   {
      file: pkg.main,
      format: 'cjs',
      sourcemap: true,
    },
    {
      file: pkg.unpkg,
      format: 'umd',
      name: 'MyLibraryName',
      sourcemap: true,
      globals: {
        vue: 'Vue',
      },
    },
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# package.json
"module": "dist/my-library-name.esm.js",
"main": "dist/my-library-name.cjs.js",
"unpkg": "dist/my-library-name.global.js",
1
2
3

Deployed on Netlify.
Последнее обновление: 2021-01-01, 09:32:47 UTC