npmパッケージの作成と公開方法
npm installで数百のパッケージをインストールしてきたあなたが、今度は自分のパッケージを公開したいと考えています。一見簡単そうに見えるプロセスですが、Node 12やCommonJSのみのセットアップ、CIシークレットに保存された長期トークンを推奨する古いチュートリアルに遭遇することになります。
このガイドでは、2025年でも正しい、モダンで安全なプラクティスを使用してnpmパッケージを作成・公開する方法を説明します。シンプルなユーティリティを構築し、適切に設定して、npm Trusted Publishingで公開します。
重要なポイント
- レガシーな
mainフィールドではなく、適切なexportsフィールドを使用したESMでモダンなパッケージ解決を実現 - 生のTypeScriptを配布するのではなく、TypeScriptを宣言ファイル付きのJavaScriptにコンパイル
- 二要素認証を有効化し、GitHub Actions OIDCを介したnpm Trusted Publishingを使用して安全な自動リリースを実現
- 公開前に必ず
npm pack --dry-runでパッケージの内容を確認
前提条件
開始する前に、以下を確認してください:
- Node.js 18以降がインストールされていること
- GitHubアカウント
- 利用者としてのnpmの基本的な知識
ESMファーストのnpmパッケージセットアップを初期化
新しいディレクトリを作成し、プロジェクトを初期化します:
mkdir use-toggle && cd use-toggle
npm init -y
git init
useToggleというシンプルなReactフックを構築します。この例では、適切なエントリーポイントを持つTypeScript npmパッケージの公開方法を示します。
モダンな公開のためのpackage.json設定
package.jsonを適切に設定されたバージョンに置き換えます:
{
"name": "@yourusername/use-toggle",
"version": "0.1.0",
"description": "A simple React hook for boolean toggle state",
"keywords": ["react", "hook", "toggle", "state"],
"license": "MIT",
"author": "Your Name",
"repository": {
"type": "git",
"url": "git+https://github.com/yourusername/use-toggle.git"
},
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
"files": ["dist"],
"engines": {
"node": ">=18"
},
"peerDependencies": {
"react": ">=18"
},
"devDependencies": {
"typescript": "^5.4.0",
"react": "^18.0.0",
"@types/react": "^18.0.0"
},
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build"
}
}
このESMファーストnpmパッケージセットアップの重要なポイント:
type: "module"はESMをデフォルトとして宣言exportsはレガシーなmainフィールドを置き換え—これがモダンなNodeがエントリーポイントを解決する方法filesは公開される内容を制御(dist/のみ)enginesはNode 18+を指定し、レガシーな互換性の問題を回避
TypeScriptコンパイルのセットアップ
tsconfig.jsonを作成:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"declaration": true,
"outDir": "dist",
"rootDir": "src",
"strict": true,
"skipLibCheck": true
},
"include": ["src"]
}
src/index.tsを作成:
import { useState, useCallback } from 'react';
export function useToggle(initial = false): [boolean, () => void] {
const [value, setValue] = useState(initial);
const toggle = useCallback(() => setValue(v => !v), []);
return [value, toggle];
}
npm run buildを実行してコンパイルします。dist/index.jsとdist/index.d.tsが生成されます—生のTypeScriptではなく、JavaScriptと型宣言ファイルです。
2025年の安全なnpmパッケージ公開
2FAを有効にしたnpmアカウントの作成
- npmjs.comで登録
- 二要素認証をすぐに有効化(WebAuthn/パスキーを推奨)
- すべての新規パッケージはデフォルトで2FA強制が有効
- 新しいセッションベースのログインモデルでは、新規・既存を問わず、すべてのパッケージの公開にはセッション中に2FAが必要
初回の手動公開
npm loginは現在2時間のセッショントークンを作成します。これらのトークンは:
- npm UIには表示されない
- 2時間後に自動的に期限切れ
- CI/CDで再利用不可
- 公開前に常に2FAを強制
非推奨のCouchDBエンドポイント経由で認証する古いツールも、移行期間中は2時間のセッショントークンを受け取ります。
初回リリースの場合:
npm login
npm publish --access public
無料アカウントでスコープ付きパッケージを公開する場合、--access publicフラグが必要です。
https://www.npmjs.com/package/@yourusername/use-toggleでパッケージを確認してください。
Discover how at OpenReplay.com.
CIでのnpm Trusted Publishing
古いチュートリアルではNPM_TOKENを作成してリポジトリシークレットとして保存するよう指示されています。このアプローチは現在廃止されています:クラシックトークンは完全に無効化され、長期間有効なCIトークンはサポートされなくなりました。
モダンな代替手段はGitHub Actions OIDC経由のnpm Trusted Publishingです。GitHubがnpmに対して身元を証明し、npmが短期間有効な認証情報を自動的に発行します—保存されたトークンは不要です。
Trusted Publishingの設定
- npmjs.comで、パッケージ → Settings → Publishing accessに移動
- GitHubリポジトリの詳細を使用して新しい「Trusted Publisher」を追加
ワークフローの作成
.github/workflows/publish.ymlを追加:
name: Publish
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm publish --provenance --access public
--provenanceフラグは、パッケージをそのソースリポジトリにリンクする暗号化証明を追加します—npmが2023年に導入したサプライチェーンセキュリティ機能です。
OIDCが使用できない場合(例:セルフホストランナー)、以下を使用して短期間有効な詳細アクセストークンを作成します:
npm token create
詳細トークンはCI公開のために2FAバイパスをオプトインでき、90日以内に期限切れにする必要があります。
古いチュートリアルで見かける内容
以下の古いパターンは避けてください:
exportsなしの"main": "index.js"—適切なESM解決のためにexportsを使用- Node 10/12/14をターゲット—Node 18+はサポートされていますが、新しいパッケージはモダンなLTSバージョン(Node 20または22)をターゲットにすべき
- CommonJSのみのパッケージ—ESMが標準;ESMファーストで配布
- すべてのワークフローでの永続的な
NPM_TOKEN—クラシックトークンは完全に無効化;トークンレスのTrusted Publishingを使用
公開前の確認
公開前に必ずローカルでパッケージをテストしてください:
npm pack --dry-run
これにより、含まれるファイルが正確に表示されます。src/やnode_modules/が表示される場合、filesフィールドの調整が必要です。
まとめ
2025年にnpmパッケージを作成・公開するには:適切なexportsを使用したESM、宣言ファイル付きのJavaScriptへのTypeScriptコンパイル、2FAの有効化、npm Trusted Publishingによるリリースの自動化を行います。レガシーパターンはスキップしてください—あなたとユーザーに頭痛の種をもたらすだけです。
よくある質問
宣言ファイル付きのコンパイル済みJavaScriptを公開してください。コンパイル済みのJSと生成された.d.tsファイルを含むdistフォルダーを配布します。これにより、異なるTypeScriptバージョンやビルドツール間での互換性が確保されます。生のTypeScriptは利用者にコードのコンパイルを強制し、バージョンの競合やビルドの遅延を引き起こす可能性があります。
dependenciesは、コードがバンドルして配布するパッケージに使用します。peerDependenciesは、Reactフック用のReactのように、利用者が提供する必要があるパッケージに使用します。これにより、最終バンドルでの大きなライブラリの重複コピーを防ぎます。パッケージは独自のバージョンをバンドルするのではなく、利用者のバージョンを期待します。
@username/package-nameのようなスコープ付きパッケージは、npmではデフォルトでプライベートになります。無料のnpmアカウントではプライベートパッケージを公開できないため、明示的に--access publicを設定する必要があります。このフラグはnpmにパッケージを公開するよう指示します。初回公開時のみ必要で、以降のバージョンはアクセスレベルを継承します。
npm deprecate @scope/packageを使用して、パッケージを削除せずにユーザーに警告します。npm unpublishによる完全な非公開は、公開から72時間以内のパッケージまたはダウンロード数が最小限のパッケージに制限されています。放棄されたパッケージの場合、非推奨が推奨されます。既存のインストールを保持しながらユーザーに警告できるためです。
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.