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

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

Настройка сборки в 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: 'SunComponentLibrary',
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": "sun-component-library",
"version": "0.1.0",
"description": "SUN component library",
"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": {
"@chromatic-com/storybook": "^3.2.6",
"@eslint/js": "^9.18.0",
"@storybook/addon-essentials": "^8.6.11",
"@storybook/addon-interactions": "^8.6.11",
"@storybook/addon-onboarding": "^8.6.11",
"@storybook/blocks": "^8.6.11",
"@storybook/react": "^8.6.11",
"@storybook/react-vite": "^8.6.11",
"@storybook/test": "^8.6.11",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.18.0",
"eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.16",
"eslint-plugin-storybook": "^0.12.0",
"globals": "^15.14.0",
"prettier": "3.4.2",
"storybook": "^8.6.11",
"typescript": "~5.6.2",
"typescript-eslint": "^8.20.0",
"vite": "^6.0.5",
"vite-plugin-dts": "^4.5.0"
},
"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 installation using 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:

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 login --registry=[адрес-репозитория]/repository/[имя-hosted-репозитория]/

Внимание!!! Важно наличие слэша / в конце команды после имени репозитория. Например, для локально развернутого Nexus:

npm login --registry=http://localhost:8081/repository/sun-component-library-hosted/

Файл с сохраненными учетными данными доступа к репозиториям в ОС Windows находится по адресу:

C:\Users\username\.npmrc

После авторизации в репозитории в файле появляется строка, которая должна иметь вид:

//[адрес-репозитория]/repository/[имя-hosted-репозитория]/:_authToken=NpmToken.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Pasted image 20250401200415.png

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

7. Публикация пакета в репозиторий

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

npm run build

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

npm publish

При выполнении такой команды без дополнительных параметров пакет будет опубликован в hosted-репозиторий, указанный в поле publishConfig.registry файла package.json (см. пример в пункте [[#2. Описание проекта в package.json]]).

Адрес hosted-репозитория для публикации можно указать явно, добавив параметр --registry:

npm publish --registry=http://localhost:8081/repository/my-test-repo-hosted/

8. Установка опубликованного пакета в сторонний проект из group-репозитория Nexus

Для установки необходимо при явно указать адрес group-репозитория с помощью параметра --registry (не забыть слэш / в конце после имени group-репозитория):

npm install sun-component-library@0.1.0 --registry http://localhost:8081/repository/my-test-repo-group/