Русский
Русский
English
Статистика
Реклама

Exports в package.json

Привет. Я работаю в команде, занимающейся улучшением пользовательского опыта
при работе с деньгами. Front-end мы поставляем npm-пакетами.

В какой-то момент я столкнулся с проблемами, которые привели меня к использованию
поля exports в package.json


Проблема #1


Пакеты могут экспортировать функции с одинаковыми названиями, но делающие разные вещи. Для примера возьмём 2 стейт-менеджера: Reatom и Effector.

Они экспортируют функцию createStore. Если попытаться экспортитировать их из одного пакета (назовём его vendors), то получится следующая картина:


// @some/vendors/index.tsexport { createStore } from '@reatom/core';export { createStore } from 'effector';

Налицо конфликт имён. Такой код просто не будет работать.


Этого можно избежать за счёт as:


// @some/vendors/index.tsexport { createStore as reatomCreateStore } from '@reatom/core';export { createStore as effectorCreateStore } from 'effector';

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

Я начал искать решение, которое позволит избежать и конфликта имён и необходимости писать as. Как бы оно могло выглядеть Например, вот так:


// @some/vendors/reatom.tsexport { createStore } from 'reatom';

// @some/vendors/effector.tsexport { createStore } from 'effector';

В двух разных файлах мы пишем обычные экспорты и импортируем нужную реализацию createStore:


// someFile.tsimport { createStore } from 'vendors/effector';

Проблема #2


Пакет vendors, скорее всего, содержит не только стейт-менеджер, а ещё какую-то библиотеку. Например, Runtypes.
Если не использовать exports, то импорт будет выглядеть вот так:


// someFile.tsimport { createStore, Dictionary, createEvent, Record } from 'vendors';

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


// someFile.tsimport { createStore, createEvent } from 'vendors/effector';import { Dictionary, Record } from 'vendors/runtypes';

А ещё хорошо бы скрыть имена библиотек. Это может быть полезно при последующих рефакторингах.


// someFile.tsimport { createStore, createEvent } from 'vendors/state';import { Dictionary, Record } from 'vendors/contract';

Решение


Чтобы добиться таких импортов, необходимо обратиться к полю exports в package.json


// package.json"exports": {  "./contract": "./build/contract.js",  "./state": "./build/state.js",  "./package.json": "./package.json"}

По сути, мы просто говорим сборщику как резолвить импорты. Если вы пишете на TypeScript, то это ещё не всё.

В package.json есть поле types, которое позволяет указать, где находятся типы пакета. В значении у него строка. Не получится указать типы и для contract, и для state. Так что же делать?

Тут на помощь приходит typesVersions в package.json


// package.json"typesVersions": {  "*": {    "contract": ["build/contract.d.ts"],    "state": ["build/state.d.ts"]  }}

Мы делаем то же самое, что и в exports, но для d.ts файлов, получая рабочие типы.


Заключение


Использование exports не ограничивается проблемой создания пакета vendors. Его можно использовать для улучшения DX.

Например, в Effector базовый импорт выглядит вот так:


import { createEvent } from 'effector';

А для поддержки старых браузеров вот так:


import { createEvent } from 'effector/compat';

Какие ещё проблемы решает exports можно ознакомиться тут.
Посмотреть на репозиторий с примером здесь.


Спасибо!

Источник: habr.com
К списку статей
Опубликовано: 09.03.2021 22:22:04
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании space307

Разработка веб-сайтов

Javascript

Typescript

Package exports

Npm

Front-end

Package.json

Exports

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru