Перейти к основному содержимому

Публикация npm пакета в Sonatype Nexus

Параметры для публикации npm-пакета. Создание npm-репозитория в Nexus, регистрация пользователя, настройка Realm.

Настройка сборки в Vite

Пример vite.config.ts с плагином vite-plugin-dts для экспорта типов TS:

vite.config.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

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

Pasted image 20250401184417.png

3. Создать роль для чтения и записи пакетов в репозиторий

Открыть форму создания роли:

  • перейти в раздел Security -> Roles
  • перейти к созданию роли кнопкой Create Role
  • заполнить поля:

Pasted image 20250401185153.png

Ниже в разделе Applied Privileges для добавления привилегий нажать Modify Applied Privileges и отфильтровать открывшийся список по значению npm, после этого выбрать привилегии:

  • nx-repository-view-npm-*-browse
  • nx-repository-view-npm-*-edit
  • nx-repository-view-npm-*-read и сохранить кнопкой Confirm:

Pasted image 20250401190722.png

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

Pasted image 20250401191109.png

Создать роль кнопкой Save.

4. Создать пользователя для публикации пакета

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

Pasted image 20250401191627.png

5. Создать репозитории

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

Pasted image 20250401192125.png

Для создания каждого из них нужно:

  • перейти в раздел Repository -> Repositories
  • перейти к созданию репозитория кнопкой Create repository.

Proxy-репозиторий

В открывшемся списке Recipe выбрать npm (proxy) и заполнить поля:

  • Name - предпочитаемое имя репозитория (добавить в конце "proxy" для идентификации);
  • Remote storage - адрес удаленного репозитория с пакетами (ввести адрес общедоступного https://registry.npmjs.org).

Остальные поля оставить по умолчанию и создать репозиторий кнопкой Create repository:

Pasted image 20250401193011.png

Hosted-репозиторий

В открывшемся списке Recipe выбрать npm (hosted) и заполнить поля:

  • Name - предпочитаемое имя репозитория (добавить в конце "hosted" для идентификации);
  • Deployment policy - политика повторного деплоя одной и той же версии.

Остальные поля оставить по умолчанию и создать репозиторий кнопкой Create repository:

Pasted image 20250401193157.png

Group-репозиторий

В открывшемся списке Recipe выбрать npm (group) и заполнить поля:

  • Name - предпочитаемое имя репозитория (добавить в конце "group" для идентификации);
  • Member repositories - список сгруппированных репозиториев, перетащить в правый столбец Members только что созданные proxy и hosted репозитории.

Остальные поля оставить по умолчанию и создать репозиторий кнопкой Create repository:

Pasted image 20250401194002.png

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

Pasted image 20250401200415.png

В случае проблем с авторизацией удалить строку из файла .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/