# Однофайловые компоненты
# Введение
Во многих проектах, глобальные компоненты определяются посредством app.component
, с последующим app.mount('#app')
для указания элемента-контейнера в теле каждой страницы.
Для проектов малого и среднего размера, в которых JavaScript используется лишь для некоторых страниц, этот подход может прекрасно работать. В более же сложных проектах или в случаях, когда весь ваш фронтенд управляется JavaScript, явными становятся следующие недостатки:
- Глобальное определение заставляет давать уникальное имя каждому компоненту
- Строковым шаблонам не хватает подсветки синтаксиса. Кроме того, приходится использовать уродливые слэши для многострочного HTML.
- Нет модульной поддержки CSS — в то время как HTML и JavaScript разбиваются на модули-компоненты, CSS оказывается за бортом.
- Отсутствие шага сборки ограничивает нас только HTML и ES5 JavaScript, не позволяя использовать препроцессоры вроде Pug (бывший Jade) и Babel
Все эти недостатки решаются однофайловыми компонентами с расширением .vue
, использование которых позволяют такие инструменты как Webpack и Browserify.
Вот простой пример файла, который мы назовём Hello.vue
:
Мы получили:
- полную подсветку синтаксиса (opens new window)
- модули CommonJS (opens new window)
- модульный CSS (opens new window)
Как и обещалось, мы также можем использовать препроцессоры, такие как Pug, Babel (с модулями ES2015) и Stylus для создания более ясных и функциональных компонентов.
Перечисленные языки даны только для примера. С тем же успехом можно использовать 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>
2
3
4
5
6
# Начало работы
# Песочница с примером
Если вы хотите прямо сейчас поиграть с однофайловыми компонентами — начните с этого простого todo приложения (opens new window) на CodeSandbox.
# Для новичков в модульных системах сборки JavaScript
С .vue
-компонентами, мы входим во вселенную продвинутых JavaScript-приложений. Это значит, что если вы этого ещё не сделали, нужно будет освоить некоторые дополнительные инструменты:
Node Package Manager (npm): Прочитайте руководство по началу работы (opens new window) о том как устанавливать пакеты.
Современный JavaScript стандартов ES2015/16: Прочитайте руководство по ES2015 (opens new window) от Babel. Нет необходимости запоминать все новые возможности, но держите эту страничку под рукой в качестве справочника.
После того как вы уделили время этим ресурсам, мы советуем вам посмотреть на 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
Это минимальный набор плагинов rollup, которые нужны для компиляции esm
модулей. Также можно добавить rollup-plugin-babel (opens new window) для транспиляции кода и node-resolve (opens new window), если используем зависимости, которые должны поставляться в итоговой сборке библиотеки.
# Конфигурирование Rollup
Для конфигурации сборки с Rollup нужно создать файл rollup.config.js
в корне проекта:
touch rollup.config.js
После создания файла нужно открыть его в любом редакторе и добавить следующий код:
// импорт используемых сторонних плагинов
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']
}
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/",
],
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',
},
},
]
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",
2
3