2026年10月8日に、GitHub Actions environmentsの現行資料を再読しました。environmentを参照するjobは、設定した保護ルールを通過してからenvironment secretへアクセスできます。required reviewers、起動者自身の承認を防ぐPrevent self-review、wait timer、許可するbranch/tagを個別に設定できますが、機能の可否はリポジトリの公開範囲とプランに依存します。environment名を書くだけで承認や安全な公開ゲートになるわけではありません。
新しいフレームワークを選んでも、変更を確認する人がいなければ不具合は残ります。逆に、HTMLと小さなJavaScriptだけで目的を満たすサイトへ、多数の道具を追加する必要はありません。
この記事ではモダンWeb開発を、変更しやすい構造を作り、変更の結果を確認し、運用を続けるための開発方法として整理します。ツールの人気順ではなく、部品の分け方、型と入力検証、ビルド、依存管理、テスト、公開の条件までをつなげます。
30秒で要点
- UI、業務ルール、外部との通信を分けると、何を変更し、何を確かめるかを整理できます。小さく分けること自体が目的ではありません。
- TypeScriptの型チェック、実行時の入力検証、テスト、実ブラウザの確認は、それぞれ違う問題を見つけます。
- 開発サーバーと本番ビルドは別です。配信するファイル、実行環境、対象ブラウザを確認します。
- CIで検査が通ることと、公開してよいことは別です。権限、秘密情報、承認、戻し方を運用に含めます。
ツールの公式仕様は2026年10月4日に確認しました。掲載する小さなJavaScript例はローカルのNode.jsで検証した範囲を示し、ブラウザやクラウドでの動作を検証済みとは扱いません。
ここでいうUIは画面の表示や操作、APIはシステム同士がデータをやり取りする窓口です。フレームワークは開発の土台となる仕組み、Node.jsはブラウザの外でJavaScriptを実行する環境を指します。
使う技術の前に、変更する仕事を整理する
静的な会社紹介、記事を多人数で更新するサイト、ログイン後にデータを操作するアプリでは、必要な構成が違います。まず「誰が何を更新するか」「どこでデータを扱うか」「失敗すると誰が困るか」を書きます。
表が収まらない場合は、横にスクロールできます
| 要件 | 最初に検討する構成 | 増える責任 |
|---|---|---|
| 内容中心で操作が少ない | HTML/CSSや静的生成、必要な部分だけJavaScript | コンテンツ更新、配信、リンクと表示の確認 |
| 操作や画面の状態が多い | UIの部品化、必要に応じてReact等 | 状態管理、画面遷移、読込・失敗時の表示 |
| 会員ごとのデータを扱う | 認証・API・サーバー処理を含む構成 | 入力検証、認可、データ保護、障害対応 |
| 編集担当が継続更新する | CMSとプレビュー・承認の仕組み | 編集権限、公開フロー、移行と保守 |
React公式は新規アプリでフレームワークを使う方針を案内し、独自構成の場合はルーティングやデータ取得などを自分で組み合わせる必要を説明しています。これは、すべてのWebページにReactが必要という意味ではありません。Reactの新規アプリ構成
Next.jsのようなフレームワークでも、静的出力とリクエスト時の処理は区別します。静的ファイルだけを置く構成では、アクセス時のCookieや動的なサーバー機能を同じように利用できません。データの更新時期と、どこで処理するかを決めてから配信先を選びます。Next.jsの静的出力
部品は、見た目とルールと通信の境目で分ける
部品化とは、ボタンをすべて別ファイルにすることではありません。一緒に変わるものをまとめ、別の理由で変わるものを切り離す考え方です。
例えば注文画面なら、数量を入力する画面、金額を計算するルール、在庫や注文を扱う通信は、それぞれ変わる理由が違います。金額計算を画面のクリック処理へ埋め込むと、計算だけ確かめたいときにも画面が必要になります。
共通化にも費用があります。似た画面でも、用途によって仕様が違うなら、無理に1部品へ押し込むと条件分岐が増えます。変更の頻度と、同じルールを守る必要性を見て決めます。
型チェックだけでは、届いた値は検証できない
TypeScriptはコード上の型の不整合を見つける助けになります。ただし型注釈は実行時の値を確認する処理にはなりません。APIから数量として文字列や負数が届く可能性があるなら、その境界で値を検証します。TypeScriptの型消去の説明
同じように、入力が正しい型でも、そのユーザーが他人の注文を変更してよいかは別の問題です。認可はサーバー側で確認し、ブラウザ上でボタンを隠すだけで済ませません。OWASPの認可の確認場所型と実データの扱いはTypeScriptとZodのAPI設計、認証と認可はWeb認証入門で深掘りできます。
小さな計算ルールを、実行できる形で分離する
次は、整数円の単価と1〜99個の数量から小計を計算する学習用の例です。税・送料・値引き・在庫・決済・注文保存は扱いません。Node.jsを使う新しい作業用フォルダーへ、次の2ファイルを同じ階層に保存します。追加パッケージやサーバー起動は不要です。
subtotal.mjs:外から渡された値を確認して計算します。
export function subtotalYen(unitPriceYen, quantity) {
if (!Number.isSafeInteger(unitPriceYen) || unitPriceYen < 0) {
throw new TypeError('単価は0以上の安全な整数円です');
}
if (!Number.isInteger(quantity) || quantity < 1 || quantity > 99) {
throw new TypeError('数量は1〜99の整数です');
}
const subtotal = unitPriceYen * quantity;
if (!Number.isSafeInteger(subtotal)) {
throw new RangeError('計算結果が整数の安全な範囲を超えました');
}
return subtotal;
}
subtotal.test.mjs:通常値だけでなく、拒否すべき入力も確かめます。
import test from 'node:test';
import assert from 'node:assert/strict';
import { subtotalYen } from './subtotal.mjs';
test('単価1200円を3個なら3600円', () => {
assert.equal(subtotalYen(1200, 3), 3600);
});
test('数量の上下限と単価0円を扱う', () => {
assert.equal(subtotalYen(1200, 1), 1200);
assert.equal(subtotalYen(1200, 99), 118800);
assert.equal(subtotalYen(0, 1), 0);
});
test('数量の不正値を拒否する', () => {
for (const quantity of [0, 100, -1, 1.5, '3', null, NaN]) {
assert.throws(() => subtotalYen(1200, quantity), TypeError);
}
});
test('単価の不正値と結果の桁あふれを拒否する', () => {
for (const price of [-1, 0.5, '1200', Infinity]) {
assert.throws(() => subtotalYen(price, 1), TypeError);
}
assert.throws(() => subtotalYen(Number.MAX_SAFE_INTEGER, 2), RangeError);
});
2ファイルを置いたフォルダーで実行します。
node --test subtotal.test.mjs
期待する結果は4テストの成功です。ファイルが見つからない場合は作業フォルダーと拡張子、import先の名前を確認します。例はNode.js 24系で実行確認しました。導入時はNode.jsのサポート状況と使う道具の動作要件を両方確認してください。確認時点では24系・22系がLTS、20系はEOLです。標準テストランナーの説明
この関数は文字列の'3'を意図的に拒否します。フォーム入力を数値へ変換するなら、空欄や空白、小数の扱いを呼び出し側で決めます。また本番の注文では、ブラウザから送られた単価を信用して請求せず、サーバーで商品と価格を確認する必要があります。関数の成功は、商取引全体の正しさを証明しません。
ビルドと依存管理で、実行条件を揃える
ビルドはソースを配信用のファイルへ変換する工程です。Viteは開発時の更新支援と、本番向けビルドを提供する道具です。フレームワーク自体や、データベース・認証・運用をすべて提供するものではありません。Viteの役割と必要環境
開発で表示できても、本番ビルドでしか起きない問題があります。例えば参照先のパス、環境変数、サーバーでしか使えない機能などです。Viteの標準的な静的出力先はdistですが、構成によって変えられます。vite previewはビルドのローカル確認用であり、本番サーバーではありません。Viteのビルドと配信
エディタはコードを書く道具、formatterは決めた書式に整える道具、Gitは変更の履歴を残す道具です。保存時の整形とCIの規約が食い違わないよう設定を共有し、実行手順をREADMEへ残します。書式が揃うことと処理が正しいことは別です。初めて履歴を扱う場合はGit入門を参照してください。
チームでは次を揃えます。lockfileは依存パッケージの版などを記録したファイル、lintは決めたコード規約等の検査、環境変数は実行環境ごとに渡す設定値です。
表が収まらない場合は、横にスクロールできます
| 揃えるもの | 揃えないと起きること |
|---|---|
| Node.js等の実行環境 | 個人のPCでは動くがCIで動かない |
| パッケージ管理ツールとlockfile | 同じソースから異なる依存関係が入る |
| 型・lint・テスト・buildの実行手順 | 人によって確認を省略したり順序を誤ったりする |
| 環境変数の一覧と用途 | 必要な値が欠ける、公開してはいけない値が混ざる |
| 配信先と対象ブラウザ | 使えないAPIや必要なサーバー機能を見落とす |
npmを採用した既存プロジェクトなら、CIのnpm ciには整合するpackage-lock.jsonが必要です。不一致なら失敗し、lockfileを自動更新しません。新しい依存を加える作業と、固定した依存を再現する作業を分けます。既存のnode_modulesを置き換える動作もあるため、対象フォルダーを確認して使います。npm ciの仕様
依存更新は一括で最新にすれば完了ではありません。変更点・互換性・セキュリティ情報を読み、影響する操作を確かめます。脆弱性チェックの結果がゼロでも、入力検証や権限設定まで正しいとは限りません。ブラウザ向けコードへ秘密のAPIキーを埋め込まないことも、依存管理とは別に確認します。Viteではクライアントへ渡す環境変数にも注意が必要です。Viteの秘密情報の扱い
テストは、見つけたい失敗に合わせる
型チェックやlintはコードを静的に調べ、単体テストは小さな処理を実行します。画面の表示や本番の通信まで、1種類のチェックで代用しないようにします。
表が収まらない場合は、横にスクロールできます
| 確認方法 | この例なら見ること | その確認だけでは言えないこと |
|---|---|---|
| 型チェック・lint | 関数の使い方、設定したコード規約 | 外部入力や業務仕様が正しい |
| 単体テスト | 小計、数量の範囲、拒否する入力 | 実画面から正しく呼ばれる |
| 結合確認 | 入力変換、API応答、失敗時の表示 | 実端末で操作しやすい |
| 実ブラウザ確認 | キーボード、拡大、送信、読み込み、戻る操作 | すべての障害や攻撃に耐える |
| 公開後の観測 | エラー、応答、重要操作、問い合わせ | 今後も故障しない |
「ボタンが有効である」と確かめるだけでは、クリック後に処理が実行されることは検証できません。試す操作と期待する結果を対にします。さらに、ネットワーク失敗時、連続操作、データが空のときも、利用者が次に何をすればよいか確認します。
W3Cの簡易確認ではキーボード操作、見えるフォーカス、フォームのラベルやエラーなどを確認できます。ただし、簡易確認だけでアクセシビリティ全体の適合を証明するものではありません。この記事のNodeテストも、実ブラウザでの確認とは分けています。CIで確認し、公開は条件を満たして進める
CIは変更を受けて検査を自動実行する仕組みです。まず、人が行っていた必要な確認を再現できるようにします。環境と依存を揃え、型・lint・テスト・ビルドの失敗が見えること、失敗した変更を先へ進めないことが出発点です。
公開工程では、対象環境、使う資格情報、承認者、戻す版、データ変更の扱いまで決めます。コードだけ戻しても、データベースの変更を戻せないケースがあるためです。プレビュー環境へ本番データや秘密情報を無条件に渡さない設計も必要です。
GitHub Actionsの環境には承認などの保護設定がありますが、利用可能な機能はプランやリポジトリの公開範囲に依存します。環境名を書くだけで自動的に承認制になるわけではありません。環境と保護ルールの公式条件
この順序を具体化する場合はCI/CD入門へ進めます。VercelやNetlify等の公開コマンドを先に実行するのではなく、採用する配信先の条件と戻し方を確認してから公開します。
導入効果は、自分たちの変更で測る
道具を入れるだけで開発時間や不具合が一定割合減るとは言えません。まず小さな変更を1つ選び、実装時間、確認時間、レビュー待ち、手戻り、公開後の問題を別々に記録します。ビルドが速くなっても、確認の抜けが増えたなら全体の改善とは言い切れません。
今回の小計例なら、仕様を変えたときに「どのファイルを直したか」「どのテストが失敗したか」「画面や通信のどこを確認し直すか」を説明できる状態が最初の到達点です。チームの引き継ぎや同種の変更でも再現できるかを見て、必要な道具を足していきます。
次に読む記事は、構成の全体像ならWeb制作完全ガイド、入力の扱いならTypeScript入門、利用者が体感する性能ならWebパフォーマンス完全ガイドです。