Подключаем библиотеку к проекту с помощью npm/yarn link

47c4470bef2e8acf8a57663213952fdb.jpeg

Привет! Меня зовут Света, я фронтенд-разработчик отдела спецпроектов в KTS.

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

У нас много библиотек: с общими утилитами и хуками, стилями, классами базовых сторов, с утилитами для ВК- и ОК-приложений. Во всех этих библиотеках нужно постоянно дополнять и заменять какие-то элементы, а после этого тестировать библиотеки на работоспособность.

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

Оглавление

В чём сложность работы с библиотеками и чем удобен наш способ подключения

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

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

Мы постепенно покрываем автотестами все свои внутренние библиотеки, но на их написание и проверку нужно потратить много времени. А npm/yarn link позволяет видеть эффект от изменений в коде библиотеки сразу же в проекте, к которому она подключена. Поэтому этот способ облегчает тестирование в реальном времени, но и не исключает важность автотестов.

Подключение и тестирование библиотеки по шагам

Вам потребуется сама библиотека и подопытный проект, на котором она будет тестироваться. Оба проекта в качестве пакетного менеджера должны использовать yarn одной версии. Ниже в статье будет также рассмотрен более частный случай, когда в зависимостях библиотеки и проекта есть React. Если у вас нет библиотеки для теста, можно взять react-testing-library. Тестовый проект можно создать с помощью одного из шаблонов Vite. Установите библиотеку в проект.

Для подключения библиотеки к проекту в большинстве случаев достаточно команды yarn link. Но бывает, что функционала yarn для линковки недостаточно, и тогда на помощь приходит npm link.

В этом примере использовалось следующее окружение:  

npm 10.2.3, yarn 1.22.21, node 20.10.0, терминал bash внутри VS Code 1.84.2, macOS Sonoma 14.1.1

Для некоторых команд могут потребоваться права администратора. В этих случаях на MacOS и Linux вы получите ошибку вида «Permission denied», а на Windows такую: «Access is denied. You do not have sufficient privileges». Для решения припишите sudo перед командой на macOS и Linux или откройте терминал с правами администратора на Windows.

Давайте представим, что тестируемая библиотека — @ktsstudio/test-library, это имя можно найти в поле «name» в package.json в проекте с библиотекой. Она склонирована в папку test-library, а тестовый проект лежит, соответственно, в папке test-project. Предполагается, что в тестовом проекте эта библиотека уже установлена.

Структура папок проектов примерно следующая:

Смотреть

5b417aed46011da75516f2502ade9451.png

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

1 — Установка зависимостей и сборка библиотеки

Для этого есть два способа.

Короткий способ — внутри проекта с библиотекой выполните команду:  

yarn install && yarn build

В начале раздела мы указали окружение, которое использовалось при проверке:  

npm 10.2.3, yarn 1.22.21, node 20.10.0, терминал bash внутри VS Code 1.84.2, macOS Sonoma 14.1.1.

В этом окружении работают оба способа. Если после выполнения всех последующих пунктов первый работает некорректно, сначала попробуйте удалить изменения в yarn.lock и переустановите зависимости в используемых проектах. Для этого можно использовать следующие команды, а затем снова выполнить шаги 1–4 текущего раздела:

root-folder $ cd test-project
test-project $ git restore yarn.lock && rm -rf node_modules/ && yarn install
test-project $ cd ../test-library
test-library $ git restore yarn.lock && rm -rf node_modules/ && yarn install

Если этот способ всё равно не работает или работает некорректно, воспользуйтесь следующим вариантом.

Длинный способ:

yarn install && yarn build

Смотреть

Структура библиотеки в node_modules тестируемого проекта

Структура библиотеки в node_modules тестируемого проекта

  • Когда вы скопировали папку dist и package.json в другой каталог, нужно выполнить команду yarn install из этого каталога, чтобы установить в нём зависимости.  Например, в папке long-way вы создали папку test-library-like, чтобы протестировать библиотеку @ktsstudio/test-library.

    Так может выглядеть структура каталога после выполнения шагов выше:

Смотреть

0a972d3e30efe6c9886ec74be8b6c247.png
  • После этого все команды, относящиеся к проекту с разрабатываемой библиотекой, нужно будет выполнять из этого же каталога. В нашем примере — из test-library-like.

Теперь нужно подключить библиотеку к тестовому проекту, а после завершения работ — отключить.

2 — Создание ссылки на экземпляры пакетов React

Если библиотека @ktsstudio/test-library под капотом использует библиотеку React, нужно учесть один нюанс. 

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

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

Для этого выполните команду npm link для react (название пакета в node_modules) и для @types/react, если они используются в библиотеке. 

❗Перед выполнением следующих команд убедитесь, что в тестовом проекте и в библиотеке нет незакоммиченных изменений в yarn.lock, так как при использовании npm link этот файл модифицируется.

Внутри проекта с разрабатываемой библиотекой выполните команды:

Например, в нашем случае команды для короткого пути будут выглядеть так:

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

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

npm list -g --depth=0

Найдите в списке экземпляр react и экземпляр его типов @types/react, где путь указывает на пакеты в составе вашего тестового проекта. На примере нашего тестового проекта это может выглядеть так:

$ npm list -g --depth=0
/Users/user/.npm-global/lib
├── @types/react@18.2.4 -> ./../../projects/test-project/node_modules/@types/react
└── react@18.2.0 -> ./../../projects/test-project/node_modules/react

В файловой системе или в интерфейсе IDE связанные экземпляры пакетов в папке node_modules тестируемой библиотеки будут иметь иконку ярлыка. Если на шаге установки зависимостей и сборки вы выбрали длинный способ, вот как может выглядеть папка node_modules:

c9995940a42d6a49cf0162d3be66a89c.png

Примечания:

  • ❗В некоторых случаях использование npm link не нужно.
    Это зависит от того, какие именно функции библиотеки используются в проекте. Например, если тестируется библиотека, которая использует react, но в тестовом проекте используются только те методы из библиотеки, в которых ничего не импортируется из react — npm link не обязателен.

  • ❗Версия node должна быть одинаковая в библиотеке и в тестовом проекте, иначе тестовый проект не увидит библиотеку по npm link.
    Проверить версию можно в package.json в поле engines.node. Если такого поля нет, в проекте будет использоваться глобально установленная версия node на вашем компьютере. Узнать глобальную версию можно с помощью команды node -v. Если глобально установленная версия node отличается от той, что указана в package.json, ее можно легко изменить с помощью менеджера версий, например NVM. Переключиться на другую версию node, которая указана в IDE или в файле .nvmrc в проекте, можно с помощью команды nvm use (предварительно потребуется установить nvm). Эта команда устанавливает нужную версию только для текущего терминала.

3 — Создание глобальной ссылки на библиотеку

Внутри каталога с библиотекой выполните команду yarn link. Так вы создадите глобальную ссылку, которую можно будет использовать в тестовом проекте. 

Убедиться, что ссылка на библиотеку создана, можно через команды:

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

$ ls ~/.config/yarn/link/@ktsstudio/test-library
dist    node_modules    package.json    src    tsconfig.json    yarn.lock

Точное название библиотеки можно найти — или задать для новосозданной библиотеки — в package.json в поле «name». 

4 — Подключение тестируемой библиотеки к проекту

Для этого внутри тестового проекта выполните команду: yarn link "@ktsstudio/test-library". Так вы заставите yarn смотреть именно в разрабатываемую библиотеку с нужными изменениями.

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

Если после этого IDE/линтер отказывается видеть ее в тестовом проекте, повторить текущий шаг.

5 — Тестирование

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

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

Ошибки

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

  • Can’t resolve 'react' / Cannot read properties of null (reading 'useCallback') и другие похожие. Для решения в терминале библиотеки выполните:

     npm link <путь до тестового проекта>/node_modules/react

    Подробнее об этой ошибке можно узнать в документации React.

Смотреть ошибку

bf1737658a0f229a708027506443235a.png740b6e104686bc49305ea7ed00153bb7.png

'ErrorBoundary' cannot be used as a JSX component и другие похожие. Подобная ошибка возникает из-за несоответствия версий пакета @types/react в тестовом проекте и в библиотеке. Для решения в терминале библиотеки выполните:

npm link <путь до тестового проекта>/node_modules/@types/react

7fda4817bac5f2b88760c7c79f79eb8b.png

  • It looks like there are several instances of «styled-components». Такого вида предупреждение может возникать в консоли при тестировании библиотеки, которая под капотом использует styled-components. Для решения попробуйте:

    1. Внутри проекта с библиотекой выполните команду npm link <путь до тестового проекта>/node_modules/styled-components/

    2. Перезапустите тестовый проект. Возможно, переустановите зависимости

    3. При завершении тестирования не забудьте отвязать ссылку: npm uninstall -g styled-components

      7777292357ab8deeaa01ed55936276b4.png

      Подробнее об ошибке в документации Styled Components.

  • В качестве общего решения, если что-то не работает, в тестовом проекте и библиотеке попробуйте эти шаги:

    1. Удалите изменения в yarn.lock: git restore yarn.lock

    2. Переустановите зависимости: rm -rf node_modules && yarn install

Как отвязать ссылку на разрабатываемую библиотеку

Вернемся к примеру с разрабатываемой библиотекой @ktsstudio/test-library. После окончания тестирования необходимо удалить созданные ссылки на библиотеки, чтобы при работе над другим проектом эти ссылки не привели к путанице и потенциальным конфликтам с зависимостями.

Для очищения ссылок нужно выполнить следующие шаги:

  1. Если вы создавали ссылки на экземпляры пакетов React — внутри каталога с собранной библиотекой или внутри тестового проекта выполните команду npm uninstall -g react @types/react. Так вы отвяжете React и его типы от собранной библиотеки. Если вы тестируете несколько библиотек, достаточно прописать это один раз.

  2. Если внутри проекта с библиотекой вы вызывали npm link, удалите оттуда изменения в yarn.lock.

  3. Внутри тестового проекта выполните команду yarn unlink "@ktsstudio/test-library"
    ❗Примечание: это нужно на всякий случай — чтобы убрать ссылку на ранее собранную библиотеку.

  4. Внутри каталога с библиотекой выполните yarn unlink
    Так вы удалите глобальную ссылку на пакет с разрабатываемой библиотекой. Убедиться, что ссылка удалена, можно, выполнив:

    • Для macOS — ls ~/.config/yarn/link

    • Для Windows — ls ~/AppData/Local/Yarn/Data/link

    • Посмотрите содержимое корневого каталога по соответствующему пути. В каталоге может присутствовать папка »@ktsstudio» (или другой префикс в зависимости от вашей тестируемой библиотеки), но папки с конкретной разрабатываемой/тестируемой библиотекой («test-library» в нашем случае) быть не должно.

  5. Внутри тестового проекта выполните yarn install --force, чтобы восстановить зависимости.

Заключение

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

Сталкивались ли вы с какими-нибудь проблемами при использовании npm/yarn link? Поделитесь в комментариях своим опытом и идеями.

Другие статьи про React:

Собираем свою библиотеку для SSR на React
Создаем текстовый редактор на React.js
Игра с голосовым управлением на React и Phaser
Что нового в react-router v6
React Drag & Drop: «Игра в бутылки»

Другие статьи про JavaScript:

• Как сверстать письмо, чтобы оно дошло до получателя таким, как задумано
Роадмэп по современному фронтенду от KTS / Хабр (habr.com)
Кастомизируем VS Code для веб-разработки / Хабр (habr.com)
Чек-лист фронтендера при разработке рекламного спецпроекта / Хабр (habr.com)
Как yarn v3 и философия Zero Installs помогли нам сократить длительность ci/cd пайплайна в 3 раза / Хабр (habr.com)

© Habrahabr.ru