Публикация npm пакета в Sonatype Nexus
Параметры для публикации npm-пакета. Создание npm-репозитория в Nexus, регистрация пользователя, настройка Realm.
Настройка сборки в Vite
Пример vite.config.ts с плагином vite-plugin-dts для экспорта типов TS:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import dts from 'vite-plugin-dts';
export default defineConfig({
plugins: [
react(),
dts({
rollupTypes: true,
tsconfigPath: './tsconfig.app.json',
}),
],
build: {
lib: {
entry: 'src/components/index.ts',
name: 'MyComponentLibrary',
fileName: (format, name) => `${name}.${format}.js`,
},
rollupOptions: {
external: ['react', 'react-dom', '@mui/material', '@emotion/react', '@emotion/styled'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
'@mui/material': 'MaterialUI',
'@emotion/react': 'EmotionReact',
'@emotion/styled': 'EmotionStyled',
},
},
},
},
});
Бандл по умолчанию помещается в папку dist/.
Имя файла определяется в коллбэке build.lib.fileName и содержит имя модуля и его формат:
es— модуль ES Modules;umd— модуль CommonJS.
Описание проекта в package.json
{
"name": "My project name",
"version": "0.1.0",
"description": "My project description",
"type": "module",
"main": "dist/index.umd.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.es.js",
"require": "./dist/index.umd.js"
}
},
"files": [
"dist"
],
"publishConfig": {
"registry": "http://localhost:8081/repository/my-test-repo-hosted/"
},
"scripts": {
"build": "tsc -b && vite build",
"lint": "eslint .",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"devDependencies": {
// ...
},
"peerDependencies": {
"@emotion/react": "^11.0.0",
"@emotion/styled": "^11.0.0",
"@fontsource/roboto": "^5.1.1",
"@mui/icons-material": "^6.4.0",
"@mui/material": "^6.0.0",
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
},
"eslintConfig": {
"extends": [
"plugin:storybook/recommended"
]
}
}
Здесь в поле exports во вложенном поле .:
types— путь к бандлу с типами;import— путь к ES Modules бандлу;require— путь к CommonJS бандлу.
В поле publishConfig.registry прописывается адрес npm hosted-репозитория в Nexus.
Настройка Sonatype Nexus
1. Установить и запустить Nexus
Развернуть Sonatype Nexus в Docker-контейнере по этой инструкции: Установка Sonatype Nexus в Docker-контейнере
2. Включить Realm для npm

3. Создать роль для чтения и записи пакетов в репозиторий
Открыть форму создания роли:
- перейти в раздел Security -> Roles
- перейти к созданию роли кнопкой Create Role
- заполнить поля:

Ниже в разделе Applied Privileges для добавления привилегий нажать Modify Applied Privileges и отфильтровать открывшийся список по значению npm, после этого выбрать привилегии:
nx-repository-view-npm-*-browsenx-repository-view-npm-*-editnx-repository-view-npm-*-readи сохранить кнопкой Confirm:

Раздел Applied Roles оставить пустым:

Создать роль кнопкой Save.
4. Создать пользователя для публикации пакета
- перейти в раздел Security -> Users
- перейти к созданию роли кнопкой Create local user
- заполнить поля с данными пользователя
- в конце формы переместить ранее созданную роль в правый столбец Granted
- создать пользователя кнопкой Create local user

5. Создать репозитории
Необходимо создать 3 репозитория: proxy, hosted и group:

Для создания каждого из них нужно:
- перейти в раздел Repository -> Repositories
- перейти к созданию репозитория кнопкой Create repository.
Proxy-репозиторий
В открывшемся списке Recipe выбрать npm (proxy) и заполнить поля:
- Name - предпочитаемое имя репозитория (добавить в конце "proxy" для идентификации);
- Remote storage - адрес удаленного репозитория с пакетами (ввести адрес общедоступного
https://registry.npmjs.org).
Остальные поля оставить по умолчанию и создать репозиторий кнопкой Create repository:

Hosted-репозиторий
В открывшемся списке Recipe выбрать npm (hosted) и заполнить поля:
- Name - предпочитаемое имя репозитория (добавить в конце "hosted" для идентификации);
- Deployment policy - политика повторного деплоя одной и той же версии.
Остальные поля оставить по умолчанию и создать репозиторий кнопкой Create repository:

Group-репозиторий
В открывшемся списке Recipe выбрать npm (group) и заполнить поля:
- Name - предпочитаемое имя репозитория (добавить в конце "group" для идентификации);
- Member repositories - список сгруппированных репозиториев, перетащить в правый столбец Members только что созданные proxy и hosted репозитории.
Остальные поля оставить по умолчанию и создать репозиторий кнопкой Create repository:

6. Авторизация в npm-репозитории
Для авторизации выполнить команду вида:
npm login --registry=[адрес-репозитория]/repository/[имя-hosted-репозитория]/
Внимание!!! Важно наличие слэша / в конце команды после имени репозитория. Например, для локально развернутого Nexus:
npm login --registry=http://localhost:8081/repository/my-test-repo-hosted/
Учетные данные репозиториев сохраняются в файле .npmrc. После авторизации в файле появляется строка вида:
//[адрес-репозитория]/repository/[имя-hosted-репозитория]/:_authToken=NpmToken.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

В случае проблем с авторизацией удалить строку из файла .npmrc и авторизоваться заново.
7. Публикация пакета в npm-репозиторий
Для публикации пакета сначала выполнить сборку бандла:
npm run build
После сборки выполнить из директории проекта команду:
npm publish
При выполнении такой команды без дополнительных параметров пакет будет опубликован в hosted-репозиторий, указанный в поле publishConfig.registry файла package.json (см. пример в разделе Описание проекта в package.json).
Адрес hosted-репозитория для публикации можно указать явно, добавив параметр --registry (не забыть слэш / в конце после имени репозитория):
npm publish --registry=http://localhost:8081/repository/my-test-repo-hosted/
8. Установка опубликованного пакета в другом проекте из group-репозитория Nexus
Для установки пакета необходимо явно указать адрес group-репозитория с помощью параметра --registry (не забыть слэш / в конце после имени репозитория):
npm install my-component-library@0.1.0 --registry http://localhost:8081/repository/my-test-repo-group/