-- Views
April 28, 26
スライド概要
npm パッケージ公開を完全に理解した
フリーランスプログラマです。 Angular, CHIRIMEN Open Hardware, MDN Web Doc 推しの人です。
npm パッケージ公開を完全に理解した エンジニア達の「完全に理解した」Talk #76
自己紹介 akihiko.KIgure a.k.a グレさん 渋谷とグンマー帝国の 2 拠点でフロントエンド開発をしています。 AI QR 生 コ ー 成 ド コ ンテンツは誤り を含む可能性があり ます。
個人的推しOSS ※アルファベット順 Angular CHIRIMEN Open Hardware Firebase
個人的推しOSS ※アルファベット順 Google Cloud MDN Web Docs Nx Rust
今日テーマ npm
今日お話する事 ● npm公開でやった事 ● 再現できる手順 ● 失敗ポイント
題材:@gurezo/web-serial-rxjs AI 生イ ア 成 コ コ ン ンテンツは誤り を含む可能性があり ます。 AI QR 生 コ ー 成 ド コ ンテンツは誤り を含む可能性があり ます。
エンジニア達の「完全に理解した」Talk #73 タイトル:Web Serial を完全に理解した ・Web Serial と RxJS を使ったライブラリ開発の LT です。 スライド Youtube connpass
npm 公開とは?
配布システムを作る事
具体的に何をするの?
最初に作りたい物を創る!
npm パッケージを使ったサンプル npm パッケージのドキュメント npm パッケージ本体
公開に向けて、やった事
● npm パッケージ用 package.json の整備 ● commit 規約の整備 ● ISSUE_TEMPLATE の作成 ● PULL_REQUEST_TEMPLATE の作成 ● CONTRIBUTING の整備 ● LICENSE の整備 ● README の整備 ● Document の整備 ● CI / Release の整備
npm パッケージ用 package.json の整備 ① ② ③ ① ④ ② ③
npm パッケージ ④
npm パッケージ用 package.json の整備 ⑤ ⑥ ⑦
npm パッケージのバージョニング(SemVer) ● バージョン形式 MAJOR.MINOR.PATCH(例:1.2.3) ● MAJOR:破壊的変更(互換性なし) ● MINOR:機能追加(互換性あり) ● PATCH:バグ修正(互換性あり)
例 ● 1.0.0 → 2.0.0:API変更(breaking) ● 1.0.0 → 1.1.0:機能追加 ● 1.0.0 → 1.0.1:バグ修正 ポイント ●利用者はバージョンで安全性を判断する ●間違えると利用者が壊れる
バージョンは“ユーザーとの契約”です
実際のバージョニング歴
commit 規約の整備 Conventional Commits に準拠した コミットメッセージに矯正(強制)します
What is Conventional Commits
@commitlint/cli コミットメッセージが 規約(Conventional Commits)に 従っているかをチェックするCLIツール
@commitlint/config-conventional Conventional Commits に準拠した ルールセットを提供する設定パッケージ
husky Gitのフック(pre-commit / commit-msg)を 設定して、コミット時に自動でチェックや 処理を実行するツール
ISSUE_TEMPLATE の作成 目的:ルールに沿って、Issue を作成する為 テンプレート種類 ● 機能改善(英語版含む) ● バグ報告(英語版含む) ● 質問 / Q&A (英語版含む) ● README / ドキュメント(英語版含む)
※海外の方が使う事も想定して、英語版も作成しました
PULL_REQUEST_TEMPLATE の作成 目的:ルールに沿って、PR を作成する為
CONTRIBUTING の整備 目的: 開発ルールや手順を明文化し誰でも同じ品質で 貢献出来る様にする為
LICENSE の整備 目的: 利用・改変・再配布の 条件を明確にし 利用者と開発者双方の 法的リスクを防ぐ為
README の整備 目的 ライブラリの概要・使い方・導入手順を明確に し、利用者が迷わず使い始められる様にする為
Document の整備 目的: API仕様や使い方を体系的に提供し 利用者が正しく効率的に活用出来る様にする為
typedoc TypeScriptのコードからAPIドキュメントを自 動生成するドキュメントツール
typedoc-rhineai-theme TypeDocの出力を見やすくカスタマイズするた めのテーマ(デザインテンプレート)
CI / Release の整備 目的: 品質を担保しつつビルド・テスト・公開を 自動化し、安定して再現性のあるリリースを行 う為
ci.yml ● CI setup ● パッケージインストール ● lint ● build ● test
commitlint.yml husky と併用して、 Conventional Commits に準拠したコミットメッセージを確認する
deploy-docs.yml typedoc で、生成されたドキュメントを git pages にデプロイします。
npm パッケージ公開用の tag $ git tag <バージョン> $ git push origin <バージョン> => release.yml のトリガー
release.yml 実行例 ● `v*` タグ push を起点に、テスト・ビルド・公開までを自動 実行する release ワークフロー ● `npm pack --dry-run` で README 同梱を事前検証し、壊れ た成果物の公開を防止 ● Trusted Publishing(OIDC)で npm に公開し、同時に GitHub Release も自動作成
Trusted Publishing(OIDC) ● CI が「正しい実行元であること」を証明して トークン無しで安全に npm publish できる仕組み
つまりどういう事 だってばよ?(なると風
従来(トークン方式) GitHub → 「パスワード(NPM_TOKEN)」を持ってる → npm にログイン 問題 パスワードを保存する必要がある パスワードが漏れたら終わり
OIDC(Trusted Publishing) GitHub → 「私はこのリポジトリです」と証明 → npm が信頼して OK 出す ポイント パスワード不要 その場限りの証明
もう少しだけ正確に
● GitHub Actions が「身分証明(OIDCトークン)」を発行 ● npm に「このワークフローから実行してます」と証明 ● npm が確認して publish を許可 しかも トークンは使い捨て(短時間で無効) 保存不要
失 敗 談
● dist が入らない => build 忘れ / files の設定不備 ● README が表示されない => README が tarball に無い ● LICENSE / note 問題 => 権利情報や release 情報が崩れている => 公開物として不完全
What is tarball
npm に公開されるパッケージの中身を まとめた圧縮ファイル(.tgz)の事
npm パッケージ公開チェックリスト ● 設計・配布物 ● 自動化・セキュリティ ● 運用ドキュメント
● 設計・配布物 □ files / exports / types を言語化できる □ dist / README / LICENSE を tarball に入れる □ prepublishOnly で build を強制する
● 自動化・セキュリティ □ PR CI で lint / build / test を前倒し □ tag release を workflow に切り出す □ OIDC / provenance の目的を説明できる
● 運用ドキュメント □ CONTRIBUTING / ISSUE / PR template がある □ RELEASING がある □ docs が公開後の利用導線になっている □ ドキュメントに英語版がある(世界公開なら必須)
npm publish は単なる1コマンドではなく 「いつでも同じ品質で公開できる仕組み」を作る事
お ま け
npm パッケージ 公開サイト
https://www.npmjs.com/ https://www.npmjs.com/ https://npmx.dev/ https://npmx.dev/
ライブラリ公開後の 累計ダウンロード数
サプライチェーン攻撃
OSSは依存関係を通じて攻撃されることがある 影響 - 自分のコードは安全でも影響を受ける - 利用者全体に広がる 対策 - バージョン管理(SemVer) - CI での検証 - 信頼できるリリースプロセス
だからこそ・・・
● バージョンをちゃんと上げる ● CI で検証する ● release をコントロールする
実施した対策
これが出来たら・・・
皆で npm パッケージを 公開しよう
そして・・・
ドヤろう(提案
まとめ npm パッケージ公開 できるよ にんげんだもの ぐれを
ご静聴ありがとうございました!