Back

npmパッケージの作成と公開方法

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.jsdist/index.d.tsが生成されます—生のTypeScriptではなく、JavaScriptと型宣言ファイルです。

2025年の安全なnpmパッケージ公開

2FAを有効にしたnpmアカウントの作成

  1. npmjs.comで登録
  2. 二要素認証をすぐに有効化(WebAuthn/パスキーを推奨)
  3. すべての新規パッケージはデフォルトで2FA強制が有効
  4. 新しいセッションベースのログインモデルでは、新規・既存を問わず、すべてのパッケージの公開にはセッション中に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でパッケージを確認してください。

CIでのnpm Trusted Publishing

古いチュートリアルではNPM_TOKENを作成してリポジトリシークレットとして保存するよう指示されています。このアプローチは現在廃止されています:クラシックトークンは完全に無効化され、長期間有効なCIトークンはサポートされなくなりました。

モダンな代替手段はGitHub Actions OIDC経由のnpm Trusted Publishingです。GitHubがnpmに対して身元を証明し、npmが短期間有効な認証情報を自動的に発行します—保存されたトークンは不要です。

Trusted Publishingの設定

  1. npmjs.comで、パッケージ → Settings → Publishing accessに移動
  2. 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.

OpenReplay