Spec-Zone.ru › Lit 3

Публикация

На этой странице приведены рекомендации по публикации компонента Lit в npm — менеджере пакетов, которым пользуется подавляющее большинство библиотек JavaScript и разработчиков. См. раздел Стартовые наборы с повторно используемыми шаблонами компонентов, подготовленными для публикации в npm.

Публикация в npm

Чтобы опубликовать компонент в npm, ознакомьтесь с инструкциями по добавлению пакетов npm в реестр.

Конфигурация package.json должна содержать поля type, main и module:

package.json

{
  "type": "module",
  "main": "my-element.js",
  "module": "my-element.js"
}

Также следует создать файл README с описанием использования компонента.

Публикация современного JavaScript

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

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

Компиляция с помощью TypeScript

Следующий пример JSON — это фрагмент tsconfig.json с рекомендуемыми параметрами для нацеливания на ES2021, включения компиляции декораторов и генерации типов .d.ts для пользователей:

tsconfig.json

"compilerOptions": {
  "target": "es2021",
  "module": "es2015",
  "moduleResolution": "node",
  "lib": ["es2021", "dom"],
  "declaration": true,
  "declarationMap": true,
  "experimentalDecorators": true,
  "useDefineForClassFields": false
}

Обратите внимание: задавать useDefineForClassFields значение false требуется только в том случае, если для target задано значение es2022 или выше, включая esnext, но рекомендуется явно убедиться, что для этого параметра задано значение false.

При компиляции из TypeScript следует указать файлы объявлений (созданные на основе приведенного выше declaration: true) с типами компонента в поле types файла package.json и убедиться, что файлы .d.ts и .d.ts.map также публикуются:

package.json

{
  ...
  "types": "my-element.d.ts"
}

Дополнительную информацию см. в документации по tsconfig.json.

Компиляция с помощью Babel

Для компиляции компонента Lit, использующего предлагаемые возможности JavaScript, которые еще не включены в ES2021, используйте Babel.

Установите Babel и необходимые плагины Babel. Например:

npm install --save-dev \
  @babel/core \
  @babel/cli \
  @babel/preset-env \
  @babel/plugin-proposal-decorators

Настройте Babel. Например:

babel.config.json

{
  "presets": [
    ["@babel/preset-env", {"targets": "defaults"}]
  ],
  "plugins": [
    ["@babel/plugin-proposal-decorators", {"version": "2023-05"}]
  ]
}

Настройте параметр "targets" так, чтобы он соответствовал браузерам, которые вы хотите поддерживать. Список доступных параметров см. в разделе @babel/preset-env.

Запустить Babel можно с помощью плагина сборщика, например @rollup/plugin-babel, или из командной строки. Дополнительную информацию см. в документации Babel.

Рекомендации по публикации

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

Не импортируйте полифилы в модули

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

Пакетам могут понадобиться полифилы для тестов и демонстраций, поэтому, если они нужны, их следует добавлять только в devDependencies.

Не объединяйте, не минифицируйте и не оптимизируйте модули

Объединение модулей и другие оптимизации относятся к ответственности приложения. Предварительное объединение повторно используемого компонента перед публикацией в npm также может добавить в приложение пользователя несколько версий Lit (и других пакетов), поскольку npm не может устранить дубликаты пакетов. Это приводит к раздуванию размера и может стать причиной ошибок.

Оптимизация модулей перед публикацией также может помешать оптимизациям на уровне приложения.

Объединение модулей и другие оптимизации могут быть полезны при раздаче модуля через CDN, но, поскольку пользователям может потребоваться использовать несколько пакетов, зависящих от Lit, раздача через CDN может привести к загрузке большего объема кода, чем необходимо. Поэтому мы рекомендуем приложениям, для которых важна производительность, всегда собирать проект из npm, где можно устранить дубликаты пакетов, вместо загрузки объединенных пакетов с CDN.

Если вы хотите поддерживать использование через CDN, мы рекомендуем четко отделить модули для CDN от модулей, предназначенных для использования в production. Например, разместите их в отдельной папке или добавляйте только в выпуск GitHub, не включая их в публикуемый модуль npm.

Указывайте расширения файлов в спецификаторах импорта

Для разрешения модулей в Node расширения файлов не обязательны: если расширение не указано, Node ищет файл в файловой системе, проверяя несколько возможных расширений. При импорте some-package/foo Node импортирует some-package/foo.js, если такой файл существует. Аналогичным образом инструменты сборки, разрешающие спецификаторы пакетов в URL-адреса, могут выполнять этот поиск в файловой системе во время сборки.

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

Карты импорта позволяют сопоставлять импорты с URL-адресами, но поддерживают только два типа сопоставлений: точное и по префиксу. Это означает, что можно легко задать псевдоним для всех модулей в заданном пакете, сопоставив имя пакета с одним URL-префиксом. Однако если писать импорты без расширений файлов, в карту импорта придется добавить отдельную запись для каждого файла пакета. Это может значительно увеличить размер карты импорта.

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

Публикация типизаций TypeScript

Чтобы элемент было проще использовать в TypeScript, мы рекомендуем:

  • Добавлять запись HTMLElementTagNameMap для всех элементов, написанных на TypeScript.

    @customElement('my-element')
    export class MyElement extends LitElement { /* ... */ }
    
    declare global {
      interface HTMLElementTagNameMap {
        "my-element": MyElement;
      }
    }
  • Публиковать типизации .d.ts в пакете npm.

Дополнительную информацию о HTMLElementTagNameMap см. в разделе Предоставление качественных типизаций TypeScript.

Самостоятельно регистрируйте элементы

Модуль, в котором объявлен класс веб-компонента, всегда должен содержать вызов customElements.define() (или декоратор @customElement) для регистрации элемента.

В настоящее время веб-компоненты всегда регистрируются в глобальном реестре. Для каждого определения пользовательского элемента необходимо использовать уникальное имя тега и уникальный класс JavaScript. Попытка дважды зарегистрировать одно и то же имя тега или один и тот же класс завершится ошибкой. Просто экспортировать класс и рассчитывать, что пользователь вызовет define(), ненадежно. Если два разных компонента зависят от одного общего третьего компонента и оба пытаются зарегистрировать его, один из них завершится ошибкой. Этой проблемы не будет, если элемент всегда регистрируется в том же модуле, где объявлен его класс.

Недостаток такого подхода заключается в том, что два разных элемента с одинаковым именем тега нельзя импортировать в один и тот же проект.

Продолжается работа над добавлением в платформу областных реестров пользовательских элементов. Областные реестры позволяют пользователю компонента выбирать имя тега пользовательского элемента для заданной области корневого элемента shadow DOM. Когда браузеры начнут поддерживать эту возможность, станет практически возможным публиковать для каждого компонента два модуля: один будет экспортировать класс пользовательского элемента без побочных эффектов, а другой — регистрировать его глобально с именем тега.

До тех пор мы рекомендуем продолжать регистрировать элементы в глобальном реестре.

Экспортируйте классы элементов

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

Дополнительная литература

Более общие рекомендации по созданию качественных повторно используемых веб-компонентов см. в документе Контрольный список Gold Standard для веб-компонентов.

Изменить эту страницу

© Google LLC
Licensed under the Creative Commons Attribution 3.0 Unported License.
https://lit.dev/docs/tools/publishing/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API