Переиспользуемый компонент Svelte: чтобы никому не было больно

Переиспользуемый компонент Svelte: чтобы никому не было больно

Компонентные фреймворки независимо от названия никогда не покинут область только нишевого использования, если сообщество не будет создавать для них общедоступные компоненты, которые можно легко встроить в свой проект.

За последние года полтора для фреймворка Svelte уже создано множество различных компонентов, которые можно найти на NPM, GitHub или официальном списке. К сожалению, не все из них правильно «приготовлены» и порой их использование раздует размер бандла приложения сильнее, чем должно быть. А бывает, что такие пакеты просто невозможно использовать, потому что его автор не силён в подготовке пакетов и упустил какие-то важные моменты.

В этой статье я расскажу как сделать и опубликовать npm-пакет со Svelte-компонентом так, чтобы им смогли воспользоваться все желающие, не получив при этом головной боли от неожиданных проблем.


Создаем компонент

Для примера решим, что мы хотим представить миру компонент, который выводит часы с анимацией смены цифр. Посмотрим на его прототип в работе тут. Обратим внимание, что весь наш компонент состоит из трех файлов. Также у него имеется внешняя зависимость в виде библиотеки 'dayjs'.

Animated clock

Для начала понадобится пустая папка. Открыв её в терминале, инициализируем создание нового npm-пакета:

  npm init

Будет предложен ряд вопросов, первый из которых захочет узнать название нашего будущего пакета. По негласному правилу пакеты, содержащие Svelte-компоненты, принято называть с префиксом svelte-, так что назовем наш пакет, например, svelte-clock-demo. Это правило совершенно необязательно, но сильно упростит поиск компонента другими людьми. Также этому поспособствует и хороший набор ключевых слов, которые нужно перечислить через запятую в одном из следующих вопросов. Оставшиеся вопросы заполняйте на свое усмотрение, можно оставить значения по умолчанию нажатием клавиши Enter.

Теперь наша папка уже не пуста, в ней появился файл package.json к которому мы вернемся чуть позже, а пока создадим новую папку components рядом с этим файлом, куда поместим все файлы нашего компонента 'App.svelte', 'Sign.svelte' и 'flip.js'.

Список файлов

Также не забудем и про внешнюю зависимость, добавим её в пакет командой:

  npm install dayjs

Необходимо указать сборщикам Svelte-проектов, где в папке находится файл компонента, чтобы они могли импортировать его. Для этого откроем файл package.json и заменим строку "main":"index.js", на:

 ...
 "svelte":"components/App.svelte",
 ...

В принципе, этого уже достаточно, можно опубликовать пакет в таком виде и большинство разработчиков смогут использовать его в своем проекте. Но большинство — это ещё не все…


Нужны модули

На текущий момент нашим пакетом смогут пользоваться только разработчики, которые делают свой Svelte-проект c настроенным сборщиком, который умеет работать с полем "svelte" в package.json. Но кроме этого, было бы неплохо если бы наш компонент могли использовать разработчики, которые делают проект на другом фреймворке или вообще без каких-либо фреймворков. Для них мы должны упаковать компонент в модули с которыми они смогут работать не настраивая плагинов для компиляции Svelte файлов в своих проектах.

ES6 модуль обычно используется при работе со сборщиками вроде Webpack или Rollup. Он должен содержать скомпилированный в JavaScript код нашего Svelte-компонента, а так же все CSS-стили, которые относятся к нашему компоненту. Однако, в модуль не должны быть включены внешние зависимости и различные вспомогательные функции из пакета svelte, например, переходы из svelte/transition или хранилища из svelte/store, а так же функции из svelte/internal. В противном случае, если пользователю понадобится использовать несколько различных пакетов, то в каждом из них будет своя копия фреймворка Svelte, что скажется на размере итогового бандла самым негативным образом.

IIFE модуль нужен для непосредственного использования в браузере в теге

Если же это проект, в котором нет настроенного компилятора Svelte, то будет импортирован ES6 модуль, и компонент инициализируется следующим образом:

import Clock from 'svelte-clock-demo';

new Clock({
  // Указываем элемент DOM, куда будет отрисован компонент
  target: document.getElementById('divForClock'),
  // Передаём свойства компоненту
  props:{
    background: 'white',
    color: 'black'
  }
})

Практически таким же образом можно использовать модуль прямо с CDN. Обычно после публикации пакета на NPM, через пару минут его версия появляется и в различных CDN сервисах, например jsdelivr.com.


  
    Страница с часами
    
    
  
  
    

Библиотека компонентов

Иногда в один пакет нужно поместить больше, чем один-единственный компонент. Яркий пример, различные библиотеки UI элементов, состоящие из компонентов вроде Input, Button, Checkbox и т.п.

В нашем пакете тоже можно предоставлять пользователю не только готовый компонент часов из App.svelte, но и компонент отдельной цифры Sign.svelte. Тогда разработчики смогут сделать на его основе, например, таймер обратного отсчета или какой-либо счетчик.

Для создания библиотеки компонентов, добавим в папку components файл index.js внутри которого сделаем ре-экспорт всех компонентов, которые мы хотим сделать доступными в нашем пакете.

export {default as Clock} from './App.svelte';
export {default as Sign} from './Sign.svelte';

Затем нужно поменять значение поля "svelte" в package.json, указав там путь до файла index.js.

  ...
  "svelte":"components/index.js",
  ...

После публикации пакета, можно импортировать только нужные компоненты:

import {Sign} from 'svelte-clock-demo';

Заключение

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

Если возникнут вопросы про публикацию компонентов, их использование или в целом по фреймоврку Svelte, ответы всегда можно получить в русскоязычном чате сообщества Svelte в Telegram.

© Habrahabr.ru