Цели вывода, интеграция с инфраструктурой, статическое веб-приложение — все может быть сложно понять с помощью трафарета. В этой статье мы рассмотрим типы целей вывода.

Я решил написать эту статью после того, как довольно долго боролся с нашей системой дизайна, созданной с использованием Stencil. Каждый компонент нашей библиотеки был включен в производственную сборку нашего приложения, даже если использовалось лишь несколько компонентов. Кроме того, каждому приложению, использующему платформу, необходимо было вызвать функцию для инициализации компонентов в реестре customElements. Излишне говорить, что это не соответствовало стандартам, которых мы стремились достичь…

Все, что я говорю в этой статье, основано на моем понимании и моем опыте. Если я в чем-то ошибаюсь или несовершенен, пожалуйста, поправьте меня.

Если вы сюда зашли, я предполагаю, что вы уже знакомы с StencilJS. Если нет, вы можете узнать об этом во введении к их документации: https://stenciljs.com/docs/introduction

Вам также может понадобиться базовое представление о веб-компонентах, которое вы можете найти здесь: https://developer.mozilla.org/fr/docs/Web/API/Web_comComponents

Введение о целевых показателях

Stencil предоставляет нам возможность писать собственные веб-компоненты на одном языке и распространять эти компоненты на множество различных целей. Их можно использовать непосредственно в собственных средах HTML/JavaScript или через оболочки, адаптированные для преобладающих сегодня фреймворков JavaScript, таких как React, Angular и Vue.

Stencil также облегчает создание документации со многими возможными целевыми выходными данными, такими как Markdown, JSON, VScode и другими.

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

Различные типы целей вывода только для веб-компонентов

Когда вы начнете изучать документацию, вы обнаружите 3 типа целевых выходных данных: dist, dist-custom-elements и www, которые являются ядром конфигураций трафарета.

Если вы здесь, потому что хотите создать повторно используемую библиотеку компонентов для всех основных платформ, вам, вероятно, интересно, о чем идет речь!

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

В вашем приложении реагирования/angular/vue, когда вы импортируете свой компонент, он использует веб-компонент в фоновом режиме.

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

Хорошо! Теперь, когда мы это понимаем, давайте углубимся в поведение различных типов выходных целей.

1 — Цель вывода веб-приложения: WWW

Цитируя документацию, тип цели вывода www ориентирован на веб-приложения и веб-сайты, размещенные на http-сервере.

Хотя Stencil в основном известен своими возможностями многократного использования библиотеки компонентов, его также можно использовать для создания полноценного веб-приложения с JSX, виртуальным домом, управлением магазином и многим другим.

Вам может быть интересно, зачем это вам нужно в повседневной работе с библиотекой компонентов. Ну, как сказано в документации: «Цель вывода www полезна для сборки и тестирования компонентов на протяжении всей разработки». Давайте посмотрим, как это сделать.

В папке src у вас есть файл index.html. В контексте веб-приложения это будет точка входа для загрузки вашего корневого компонента, но в контексте библиотеки это будет ваша среда тестирования.

Когда вы запустите «npm start», он создаст цель вывода WWW и запустит index.html в вашем веб-браузере. По умолчанию он реализован с перезагрузкой в ​​реальном времени, поэтому вы можете работать над своим компонентом в файле TS и тестировать его реализацию в index.html.

Результатом сборки www будет новая папка «www» в корне вашего проекта с:

  • index.html: корневой файл веб-приложения.
  • Папка сборки: каждый компонент разделен в отдельный файл для отложенной загрузки + глобальные файлы.

Вы можете найти дополнительную конфигурацию на странице документации или пример веб-приложения на github.

2 — Цель распределения выходного сигнала: расст.

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

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

Что вы можете найти в папке сборки:

  • Папка cjs и esm: готовый к сборке файл javascript для commonjs и модулей.
  • коллекция: файлы трафаретов, преобразованные в простой JavaScript. Это файлы, которые используются, если вы импортируете свою библиотеку в другой дистрибутив трафаретов.
  • загрузчик: запись бандлера для отложенных загружаемых сборок (используется, например, для одновременной регистрации всех компонентов в реестре веб-компонентов с помощью функции defineCustomElements).
  • output-target-stencils (имя рабочей области приложения): компонент, готовый для браузера.
  • типы: типы машинописных текстов с файлами d.ts.

Давайте попробуем!

Чтобы предотвратить ошибки CORS в Chrome, мы запустили небольшой сервер с помощью библиотеки serve в корне нашей папки. Мы получаем URL-адрес localhost:3000 для нашего проекта.

Существует другой способ использования сборки компонента с выводом dist.

Первый использует готовые для браузера компоненты и импортирует их непосредственно в тег ‹head›.

Он зарегистрирует все компоненты в реестре customElements.

Но благодаря ленивой загрузке в браузере загружается только тот, который используется в index.html.

Второй — использовать загрузчик, результат тот же. Компоненты загружаются отложенно.

Наконец, вы можете отправить свою библиотеку в виде пакета на npm и импортировать ее в свой проект. Я не буду показывать здесь пример, но вы можете воспользоваться документацией: https://stenciljs.com/docs/distribution#importing-the-dist-library-using-a-bundler

3 — Пользовательские элементы: dist-custom-elements

Эту последнюю цель я определю так: получите минимум и делайте все сами.

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

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

Давайте посмотрим, почему все же было бы хорошей идеей его использовать.

Как и в предыдущем случае, начнём с минимальной конфигурации dist-custom-elements.

Папка dist намного меньше, чем для цели вывода «dist», без разделения esm/cjs. Никакой коллекции для повторного использования в другом проекте трафарета, только компоненты в отдельных файлах.

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

Мы видим, что у каждого компонента есть собственный CSS.

Здесь мы видим аннотацию /*@__PURE__*/, которая укажет сборщику, что этот компонент является чистым, что означает, что если он не вызывается напрямую вашим приложением. Его можно смело игнорировать при связывании (тряска дерева).

Каждый экспортируемый компонент имеет собственную функцию defineCustomElement, поэтому мы можем регистрировать каждый компонент один за другим.

Давайте немного поиграем с конфигурацией. Чтобы компонент работал в автономном index.html, как и раньше, мне нужно установить для конфигурации externalRuntime значение false, поскольку импорт типа @stencil/core не работает без упаковщика.

Итак, без какой-либо другой конфигурации (ожидайте, externalRuntime: false), мне нужен HTML, как показано ниже, чтобы использовать компонент.

И, как и ожидалось, в реестре customElements зарегистрирован только мой компонент.

Мы можем поиграть с параметром конфигурации customElementsExportBehavior.

  • auto-define-custom-elements :функция defineCustomElement будет вызываться непосредственно внутри файла компонента, поэтому вам просто нужно импортировать файл, чтобы компонент заработал.

  • bundle : сделает доступной, как и в цели вывода dist, функцию defineCustomElements в файле index.js для одновременной регистрации всех компонентов.

  • single-export-module: позволяет импортировать все компоненты из файла index.js.

Эти возможности конфигурации для dist-custom-elements станут действительно интересными, когда вы начнете добавлять цель вывода фреймворка: https://stenciljs.com/docs/overview

Заключение

StencilJS — отличный фреймворк, поскольку он обеспечивает гибкость конфигурации проектов и позволяет создавать пакеты для всех возможных вариантов использования. Это особенно здорово, потому что вы можете создать свою библиотеку компонентов со всеми возможными целевыми объектами вывода и позволить приложению, использующему вашу библиотеку, решать, как они хотят ее импортировать.

В конфигурации между различными целями вывода для веб-компонентов может возникнуть путаница, и немного сложно понять разницу между dist и dist-custom-elements.

Поскольку эта статья получилась довольно длинной, я решил поместить информацию об интеграции фреймворка в другую статью, где я предоставлю репозиторий GitHub для сложной настройки трафарета с интеграцией с пользовательской фреймворком.

Следите за обновлениями…

РЕДАКТИРОВАНИЕ: вот вторая часть => https://alexandreolive.medium.com/unlocking-cross-framework-power-stenciljs-configuration-demystified-cd12933b1aaf

Спасибо, что дочитали до конца. Если вам понравился контент, подпишитесь на него.