目次
- はじめに
- 環境
- コマンドを実行するディレクトリ
- PlaywrightはTypeScriptを実行できるが、型チェックは別
- Playwright専用のtsconfig.jsonを作る
- Node.jsの型が足りない
types: ["node"]は何をしているのかESNextが必要になった理由DOMが必要になった理由module: "NodeNext"の意味strict: truenoEmit: trueincludeでPlaywrightだけを対象にする- 型チェックを実行する
- npm scriptにする
- 今回理解できたこと
- まとめ
- 公式一次情報
- 関連記事
はじめに
前回は、Laravel 13 + WSL環境の既存プロジェクトへPlaywright Test、TypeScript、Chromiumを導入しました。
しかし、PlaywrightをTypeScriptで使う準備は、typescriptパッケージをインストールしただけでは終わりませんでした。
Playwright用のTypeScript設定を作成して型チェックを実行すると、次のような型エラーが発生しました。
Buffer
fs
stream
child_process
Symbol.asyncDispose
Node
HTMLElement
SVGElement
HTMLElementTagNameMap
最初は別々のエラーに見えましたが、整理すると不足していたものは大きく3種類でした。
Node.jsの型
JavaScript標準APIの型
ブラウザDOM APIの型
この記事では、実際に遭遇した型エラーを追いながら、
@types/node
types: ["node"]
lib: ["ESNext", "DOM"]
module: "NodeNext"
strict: true
noEmit: true
がそれぞれ何のために必要だったのかを整理します。
環境
Playwright導入時点の環境です。
PHP 8.4.24
Laravel 13.26.1
Node.js 24.19.0
npm 11.17.0
Playwright Test 1.62.1
TypeScript 7.0.2
@types/node 24.13.3
WSL Ubuntu 24.04
Playwright / Node.js / npm / TypeScriptはWSL側で管理しています。
コマンドを実行するディレクトリ
今回も、WSLのUbuntu上でLaravelプロジェクトのルートへ移動してから実行します。
cd ~/projects/review-app-laravel
Laravelプロジェクトルートには次のようなファイルがあります。
artisan
composer.json
package.json
package-lock.json
vite.config.js
以降のnpm、npx、TypeScript関連コマンドは、特に記載がない限りこのディレクトリで実行します。
PlaywrightはTypeScriptを実行できるが、型チェックは別
Playwright TestはTypeScriptをそのまま読み込み、JavaScriptへ変換して実行できます。
そのため、次のようなTypeScriptのテストファイルを事前に手動コンパイルしなくても実行できます。
import { test, expect } from '@playwright/test';
ただし、ここで重要なのは、
PlaywrightがTypeScriptを実行できる
≠
TypeScriptの型エラーを検出してくれる
という点です。
Playwright公式でも、Playwright自身はTypeScriptの型チェックを行わないため、TypeScript compilerを別途実行することが推奨されています。
そこで今回は、Playwright用TypeScriptだけを対象にしたtsconfig.jsonを作成し、
npx tsc -p e2e/tsconfig.json --noEmit
で型チェックする構成にしました。
Playwright専用のtsconfig.jsonを作る
既存Laravelプロジェクト全体をTypeScript化するのではなく、Playwright用のコードだけを型チェックしたかったため、
e2e/tsconfig.json
を作成しました。
Playwright公式でも、テスト固有の設定を変更できるよう、テストディレクトリ内へ独立したtsconfig.jsonを置く方法が案内されています。
最終的な設定は次の形になりました。
{
"compilerOptions": {
"module": "NodeNext",
"strict": true,
"noEmit": true,
"lib": ["ESNext", "DOM"],
"types": ["node"]
},
"include": [
"./**/*.ts",
"../playwright.config.ts"
]
}
補足
この
tsconfig.jsonは、Playwrightのテスト実行だけでなく、tscによる型チェックにも使用しています。Playwright自身がテストを変換・実行するときに参照する
tsconfigのオプションは一部に限られます。
今回設定したmodule、strict、lib、types、noEmitは、主にtscでPlaywright用TypeScriptを型チェックするための設定です。
ここから、なぜこの設定になったのかを1つずつ見ていきます。
Node.jsの型が足りない
最初に不足したのが、Node.js固有の型でした。
代表的には次のようなものです。
Buffer
fs
stream
child_process
これらはブラウザAPIではなく、Node.js側で提供される機能です。
そこでNode.js 24系に合わせて、Node.js用型定義を追加しました。
npm install --save-dev @types/node@24
導入後の確認です。
npm ls @types/node --depth=0
今回の導入結果は、
@types/node@24.13.3
でした。
@types/nodeはPlaywrightやTypeScriptと同じくdevDependenciesとして管理します。
types: ["node"] は何をしているのか
@types/nodeをインストールしたうえで、tsconfig.jsonには次を設定しました。
{
"compilerOptions": {
"types": ["node"]
}
}
TypeScriptのtypesオプションを指定すると、グローバルスコープへ含める@typesパッケージを明示できます。
今回使用しているTypeScript 7.0.2では、typesの既定値は空配列です。
そのため、
{
"compilerOptions": {
"types": ["node"]
}
}
とすることで、@types/nodeが提供するNode.jsのグローバル型をPlaywright用TypeScriptの型チェック対象へ明示的に含めています。
たとえば、
Buffer
process
などのNode.js環境のグローバル型を利用できるようになります。
ESNext が必要になった理由
次に不足したのが、
Symbol.asyncDispose
など、新しいJavaScript標準APIに関する型でした。
TypeScriptのlibでは、どのJavaScript標準ライブラリの型定義を利用するか指定できます。
そこで、
{
"compilerOptions": {
"lib": ["ESNext"]
}
}
を追加しました。
ESNextを指定することで、新しいECMAScript標準APIの型定義を利用できるようにしています。
DOM が必要になった理由
さらに、
Node
HTMLElement
SVGElement
HTMLElementTagNameMap
といったブラウザ側の型も不足しました。
これらはNode.jsの型ではなく、ブラウザDOM APIの型です。
TypeScriptでは、ブラウザ環境で提供されるdocumentなどの型はDOMライブラリに含まれます。
そこで最終的に、
{
"compilerOptions": {
"lib": ["ESNext", "DOM"]
}
}
としました。
今回のPlaywrightコードでは、
Node.js側
+
ブラウザ側
の両方の型を扱う必要があります。
そのため、
types: ["node"]
→ Node.js
lib: ["ESNext", "DOM"]
→ JavaScript標準API + ブラウザDOM
という役割分担になりました。
module: "NodeNext" の意味
今回のLaravelプロジェクトのpackage.jsonには、
{
"type": "module"
}
が設定されています。
ただし、"type": "module"だから必ずNodeNextでなければならない、という意味ではありません。
今回のPlaywright設定やE2EコードはNode.js上で実行するため、TypeScript側もNode.jsのES Modules / CommonJSの判定規則に合わせる目的で、
{
"compilerOptions": {
"module": "NodeNext"
}
}
を採用しました。
NodeNextでは、ファイル形式や最寄りのpackage.jsonにある"type"などをもとに、Node.jsと同様のモジュール判定を行います。
また、module: "NodeNext"を指定すると、モジュール解決もNode.js向けのNodeNext方式になります。
今回の関係は、
Playwright設定 / E2Eコード
→ Node.js上で実行
package.json
→ "type": "module"
TypeScript
→ module: "NodeNext"
という整理です。
strict: true
次に、
{
"compilerOptions": {
"strict": true
}
}
を設定しました。
strictは、TypeScriptの複数の厳格な型チェックをまとめて有効にする設定です。
Playwrightのテストコードでも、
存在しない可能性のある値
型が不明確な値
null / undefined
などを早い段階で検出できるようにするため、有効にしています。
noEmit: true
今回、TypeScript compilerの役割はJavaScriptを生成することではありません。
Playwright自身がTypeScriptを読み込み、実行時に変換してくれるためです。
そのため、
{
"compilerOptions": {
"noEmit": true
}
}
としました。
TypeScript公式でも、noEmitはJavaScriptやsource mapなどの出力を生成せず、TypeScriptを型チェッカーとして使う用途に利用できる設定です。
つまり今回の役割分担は、
Playwright
→ TypeScriptを実行
tsc
→ 型チェックだけ行う
です。
include でPlaywrightだけを対象にする
最後に型チェック対象を限定しました。
{
"include": [
"./**/*.ts",
"../playwright.config.ts"
]
}
e2e/tsconfig.jsonから見て、
./**/*.ts
→ e2e/配下
../playwright.config.ts
→ プロジェクトルートのPlaywright設定
を対象にしています。
今回の目的はPlaywright用TypeScriptの型チェックなので、既存の
resources/js/
までTypeScript化したり、型チェック対象へ広げたりはしていません。
これにより、既存Laravelフロントエンドへ不要な影響を広げず、E2Eコードだけを独立して管理できます。
型チェックを実行する
設定後、次のコマンドを実行しました。
npx tsc -p e2e/tsconfig.json --noEmit
tsconfig.json側でもnoEmit: trueを設定しているため、コマンドラインの--noEmitは機能上は重複します。
ここでは、実際のプロジェクトで使用している型チェックコマンドをそのまま掲載しています。
ここまで対応したことで、導入時に発生していた型エラーは解消しました。
npm scriptにする
毎回長いコマンドを書く必要がないよう、package.jsonへ次のscriptを追加しました。
{
"scripts": {
"typecheck:e2e": "tsc -p e2e/tsconfig.json --noEmit"
}
}
以降は、
npm run typecheck:e2e
でPlaywright用TypeScriptだけを型チェックできます。
今回理解できたこと
今回の型エラーは、単に「TypeScriptの設定が足りない」という1種類の問題ではありませんでした。
Buffer / fs / stream
→ Node.jsの型
Symbol.asyncDispose
→ 新しいJavaScript標準APIの型
HTMLElement / Node / SVGElement
→ ブラウザDOMの型
と、実行環境ごとに必要な型が分かれていました。
最終的には、
@types/node
→ Node.js型定義そのもの
types: ["node"]
→ Node.js型をグローバル型として利用
ESNext
→ 新しいJavaScript標準API
DOM
→ ブラウザAPI
NodeNext
→ Node.jsのmodule解決
strict
→ 厳格な型チェック
noEmit
→ JavaScriptを生成せず型チェックだけ実行
という役割を整理できました。
まとめ
今回は、Playwright用のTypeScript設定を独立させ、実際に遭遇した型エラーを解消しながらtsconfig.jsonの意味を整理しました。
最終構成は次のとおりです。
{
"compilerOptions": {
"module": "NodeNext",
"strict": true,
"noEmit": true,
"lib": ["ESNext", "DOM"],
"types": ["node"]
},
"include": [
"./**/*.ts",
"../playwright.config.ts"
]
}
次回は、Playwrightの基本設定として、
testDir
workers
baseURL
screenshot
trace
video
Chromium project
を設定し、PHPUnitとは別にE2Eテストを配置する構成を整理します。
公式一次情報
この記事の内容は、次の公式ドキュメントを確認しながら整理しています。
- Playwright - TypeScript
- TypeScript TSConfig - module
- TypeScript TSConfig - lib
- TypeScript TSConfig - types
- TypeScript TSConfig - strict
- TypeScript TSConfig - noEmit
参照日: 2026-09-06
PlaywrightやTypeScriptの仕様は更新されるため、実際に設定する際は最新版の公式ドキュメントも確認してください。