Главная » Хабрахабр » Тестируем создание библиотеки компонент для Angular с помощью новой команды для Angular/Cli — library

Тестируем создание библиотеки компонент для Angular с помощью новой команды для Angular/Cli — library

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

В конце июля, команда Angular предложила свое, комплексное, решение этой проблемы добавив в angular/cli новую команду для создания библиотек — library. Проблема в том, что второй вариант требует значительных усилий по подготовке и каждый такой проект уникальный — со своим инструментарием в котором каждому новому разработчику нужно разбираться заново.

Давайте посмотрим, что из этого получилось.

1. Для тестов, взята самая свежая из стабильных версий angular/cli — 6. 09. 5 (04. 2018)

Идеальный мир

Так, для библиотеки компонент я бы выделил три важных момента В идеальном мире все должно быть удобно.

  • Единообразность проектов и быстрый старт
  • Удобство разработки
  • Удобство распространения

Итак начем со старта

Сначала создадим новый проект: Для того что бы создать свою библиотеку нам нужно сделать два шага — создать новый проект и добавить к нему библиотеку.

npx @angular/cli@latest new mylibapp

npx

Если у вас npm версии 5. Я использую npx что бы не устанавливать cli глобально и избегать npm run конструкций. Подробнее почитать можно здесь 2 или новее — попробуйте.

Сам angular проект теперь описывается в angular.json. После выполнения команды, мы увидим стандартный (для 6 ангуляра, который отличается от 5ой версии) проект в котором будут созданы два под-проекта — основной mylibapp и mylibapp-e2e.

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

Наше название уже занято основным проектом, и назвать библиотеку так же уже не выйдет. И вот он первый нюанс. Например, my-super-library-project. Поэтому, если вы хотите назвать библиотеку my-super-library, сначала нужно создать проект, который должен называться как-то по-другому. И только потом, создавать библиотеку с желаемым названием.

Теперь создадим третий под-проект и сгенерируем библиотеку.

cd mylibapp
npx ng generate library mylib --prefix mlb

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

Она имеет свой отдельный package.json, tsconfig и karma.conf.js, что позволяет настраивать ее без боязни задеть остальные проекты. Как видно, теперь, третьим под-проектом добавилась наша наша библиотечка. Но вот почему библиотеку нельзя было выделить совсем отдельным проектом (как например в . Кстати, при желании мы можем добавить еще одну библиотеку и она тоже будет отдельным подпроектом. И если e2e проект не сложно удалить руками, то основной проект — уже нет. Net) я не знаю. В итоге в репозитории появляется лишний код, что не очень хорошо.

Это связка tslint + codelyzer, karma + jasmine и protractor для e2e. Теперь давайте посмотрим, какие инструменты мы получаем сразу. стандартный набор angular проекта, ничего специфичного для библиотеки нам не подвезли. Т.е. Но ладно, будем считать, что тут нам просто оставили пространство для маневра. Это немного странно, так как какой-то инструмент для просмотра компонент и рендера их в документацию (например storybook) просто must have.

Давайте запустим тесты и линтер что бы убедиться, что все работает.

npm test mylib
npx ng lint mylib

Я ничего против него не имею, но на билд серверах его на 90% не будет. У меня все прошло без проблем, но для тестирования был использован Chrome, что тоже странно. Почему не использовали тот же Puppeteer — не понятно.

Подведем итоги:

Плюсы

  • Быстрый старт нового проекта
  • Единообразный подход

Минусы

  • Лишний код в проекте
  • Очевидные вещи нужно допиливать руками

Пока ничего критичного, продолжаем копать дальше.

Разработка

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

немного кода

npx ng build mylib

import from "mylib"; ... @NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, MylibModule ], providers: [], bootstrap: [AppComponent] })

npm start

Но снова есть нюанс — watch режим для библиотеки пока не сделали, нужно каждый раз запускать билд библиотеки самостоятельно? После того как все выполнится, мы увидим наш компонент из библиотеки. 2+. Watch появится только в angular/cli 6. И не из коробки, для этого придется добавить новый флаг в tsconfig.json

tsconfig.json

"angularCompilerOptions": { "enableResourceInlining": true,
}

А после этого запускать билд c флагом watch:

ng build mylib --watch

2, билдить придется самостоятельно, что, прямо скажем, — плохо. Если же вы в силу каких-то причин будете использовать cli младше 6.

Для этого нужно выполнить стандартную команду generate component. Теперь давайте добавим новый компонент. Из-за того, что библиотека не наш основной проект, приходится использовать флаг проекта, что тоже немного раздражает (а вот если бы библиотека была самостоятельным решением...).

npx ng generate component some-nice-image --project mylib

И тут нас ждет еще один сюрприз — картинки нет. Теперь под mylib/src создадим папку assets, добавим картинку и снова пересоберем библиотеку что бы увидеть резульат. И вроде бы не страшно, но все равно как-то не правильно. Оказывается, что ресурсы, используемые в библиотеке не попадают в билд автоматически, их нужно копировать самостоятельно (или вот так).

Давайте создадим еще один компонент в библиотеке но не будем использовать его в основном проекте. Зато, из-коробки должен работать tree-shaking. Собираем основной проект в продакш режиме

npx build --prod

Tree-Shaking с библиотеками действительно работает! И видим, что размер бандла не изменился.

Поскольку каждый проект имеет свой собственный package.json нам нужно сначала перейти в папку библиотеки и выполнять команду npm install Теперь неплохо было бы попробовать поставить какую-то зависимость.

npm i -D @drag13/when-do
npm i @drag13/round-to

Все ставится без проблем. Я специально поставил их по-разному что бы проверить как потом с этим справится упаковщик. Пробуем собрать и получаем предупреждение

Please consider adding drag13/round-to to 'peerDependencies'or remove it from 'dependencies Distributing npm packages with 'dependencies' is not recommended.

Пожалуйста, подумайте, что бы добавить зависимость drag13/round-to к peerDependencies или вообще убрать ее из зависимостей Распространение npm пакетов с зависимостями не желательно.

а, затем, и ошибку:

Dependency drag13/round-to must be explicitly whitelisted

Зависимость drag13/round-to должна быть явно добавлена в белый список

Пробуем переместить нашу зависимость в секцию peerDependencies и собраться заново – вуаля, все работает. Вот это уже интересно, by design, библиотека не хочет иметь прямых зависимостей. Сначала ставим зависимость на основной модуль, потом, ручками добавляем в секцию peerDependencies библиотеки. Но это значит порядок установки сторонних библиотек теперь другой.

Остальное работает так же, как и в обычном Angular проекте.

Коротко подведем итоги:

Плюсы:

  • Работаем в знакомом окружении со знакомыми командами
  • Есть tree-shaking из коробки

Минусы:

  • Для "посмотреть компонент" нужно использовать целый проект
  • Пока еще нет watch режима
  • Ресурсы нужно копировать вручную или настраивать билд-процесс самостоятельно.

И, наконец, переходим к публикации

Публикация

Для публикации angular/cli использует уже неплохо зарекомендовавший себя ng-packgr который самостоятельно собирает наш код в пригодный для публикации npm пакет оставляя за бортом настройку package.json файла (а это не мало), минификацию, упаковку в разные форматы (например в UMD). Вот тут все прямо хорошо.

Для того, чтобы опубликовать свой пакет (или посмотреть что там внутри) нужно выполнить три команды

npx ng build --prod
cd dist/mylib
npm publish

Если вы не хотите паблишить, замените команду publish на pack

В результате у меня получилось следующее:

Для начала давайте заглянем в package.json, который выглядит совсем не так оригинальный package.json нашей библиотеки.

Кроме того теоретически радует количество форматов, которые описаны в package.json (пусть я и половины их не знаю). Как видим, packagr не стал удалять наши devDependencies, хотя некоторые так делают.

Но, главное, теперь об этом не будет болеть голова разработчиков что просто замечательно. Внутри пакет содержит минифицированный и не минифицированный бандл в формате UMD, и еще несколько бандлов внутреннего формата angular (fesm5, fesm2015).

Перейдем к выводам

Плюсы:

  • Удобство
  • Продуманность

Итого

Старт и публикация очень удобны, но к разработке пока есть вопросы. Решение получилось интересное, но сырое. Особенно растраивает, что сейчас библиотека не является самостоятельным проектом by design, а скорее дополнением к основному проекту с возможностью публикации.

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


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Триумф и трагедия «Бурана»

В полностью автоматическом режиме он совершил 2 витка вокруг Земли и успешно приземлился спустя 205 минут. Ровно 30 лет назад с космодрома Байконур на ракете-носителе «Энергия» в свой единственный полёт отправился корабль «Буран». Это стало несомненным триумфом советской космонавтики, впервые ...

[Из песочницы] Несертифицированный GPS-трекер из Китая. Законно ли в России?

Иностранные интернет-магазины завалены разнообразными устройствами, оснащёнными GPS, GSM-модулями, позволяющими отслеживать местоположение наблюдаемого объекта и управлять устройством посредством SMS и мобильных приложений. И, конечно же, большинство из них не сертифицированы и запрещены для ввоза/использования в России. Простой обыватель, услышав слова «несертифицированный» ...