preact serve が動かない
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ AppData\Roaming に preact-cli フォルダを自分で作らないとダメ
◆ 証明書作成用の関数がおかしいので修正必要
◆ 証明書作成用の関数がおかしいので修正必要
preact は htm と合わせた standalone で使うくらいで webpack とか事前ビルドは全然使ってなかったのですが preact-cli というのをみかけたので使ってみました
https://github.com/preactjs/preact-cli
バージョンは現最新版の 2.2.1 です
だと default がテンプレートで test1 が作るフォルダ名です
SSR に対応していたり ServiceWorker ファイルまで作ってくれたり思った以上に高機能です
ただ個人的には内部でよくわからないことを色々されてるのがあんまり好きじゃないので standalone 版で使うだけでいいかなって気はしました
default と simple は問題なく動いたのですが material テンプレートだけは serve ができません
こんなエラーが起きます
他では動いたのにと思って serve コマンドを見てみると default と simple では sirv を使っていました
どちらも serve コマンドの中身はこれです
https://github.com/preactjs-templates/default/blob/master/template/package.json
https://github.com/preactjs-templates/simple/blob/master/template/package.json
それに対して material の場合はこれです
https://github.com/preactjs-templates/material/blob/master/template/package.json
普通に preact-cli の serve を使ってます
preact serve 自体がダメのようですね
最後に出てるエラーは ENOENT です
これはファイルやフォルダがみつからないってエラーです
preact-cli の serve では http2 サーバを作って serve するようで そのために simplehttp2server というツールを使っています
create のときの自動インストールでエラーでもあったのかなと見てみるとエラーが出ているパスにはちゃんと exe が存在しました
よくわからないのでとりあえず直接その exe を実行してみるとサーバが起動して普通にブラウザからアクセスして使えました
build だけして serve は別に手動でやってもよさそうです
ただ ちゃんと解決したいなとも思うので 続けて調べてみました
この exe を実行している箇所で引数を表示してみると cwd に 「ユーザフォルダ\AppData\Roaming\preact-cli」 を指定していました
しかし Roaming 以下に preact-cli フォルダはないのでこっちが見つからずエラーです
エラーを見ると実行するファイルのほうが無いように見えますが原因は cwd の方でした
わかりづらいですね
原因は preact-cli が自分で使うフォルダなのにフォルダを作ってないことのようです
手動でこのフォルダを作ったらそこのエラーはなくなりました
……が また別の問題が起きました
このメッセージが出た状態でそこから進みません
もうサーバの起動が完了してるのかなとデフォルトポートの 8080 にアクセスしてもつながりませんでした
これが正常というわけではないようです
プロセスを見てみると simplehttp2server 自体は起動していました
ただ 「-listen 40210」 というオプションがついていて 8080 ではないです
どこから 40210 が出てきたんだろうと ソースを見ていると証明書作成処理で止まってるようです
https://github.com/preactjs/preact-cli/blob/v2.2.1/src/lib/ssl-cert.js#L28
さっきはなかったのにと思ったら 同じく cwd がなくてエラーなのでスキップしてたようです
よく見るとログに「Failed to generate dev SSL certificate:」というのもありました
わざわざ別の場所に証明書作らなくても直接 simplehttp2server を起動したら動いたので不要な処理に見えます
消してしまおうかとも思ったのですがせっかくあるのでこのまま動かそうと修正してみます
spawnServerForCert 関数を見ると色々実装がおかしいです
まず execFile のコールバック関数は実行が終わってから呼び出されるのに 実行中に呼び出される前提のようなコードです
simplehttp2server のプログラム自体は自動で終了しないので 標準出力から 「listening」 を受け取ると証明書作成は完了したとみなしてプロセスを kill しています
またタイムアウトのチェックのタイマーを開始したりしています
パット見だと良さそうですが これらの処理が実行されるのは simplehttp2server の処理が終わってからです
kill しないと終わらないのですから これらが実行されることはありません
書いた人が spawn などの関数と間違って使ってそうです
これを spawn に置き換えてコールバック関数ではなく返り値を使って同様の処理にすれば動きます
ただ 「listening」 を含むかのチェックに正規表現を使ってますが RegExp に match メソッドは存在しません
正しくは test です
ここも修正必要です
実際に実行されてるのはバンドル済みなのでこういう感じに修正しました
ここを直して再実行したら
正常ぽいメッセージです
「https://localhost:8080/」にアクセスしたらページが見れました
preact 関係とかそこそこ大きな規模のプロジェクトですし リリース前に厳し目のレビューやテストがありそうなイメージでしたがそうでもなさそうですね
それに合わせて ssl-cert.js ファイルもなくなってます
問題も多いし sirv とか別のツールつかえばいいじゃんとなったのでしょうか
serve 機能自体 デバッグ用ですし わざわざ作るほどじゃないと判断したのかもです
react の react-scripts と vue の vue-cli では webpack-dev-server でした
無難に webpack 任せでいいのかもしれませんね
https://github.com/preactjs/preact-cli
バージョンは現最新版の 2.2.1 です
create
preact create を使えば用意されてるテンプレートを使ってすぐに使える状態にしてくれますpreact create default test1
だと default がテンプレートで test1 が作るフォルダ名です
SSR に対応していたり ServiceWorker ファイルまで作ってくれたり思った以上に高機能です
ただ個人的には内部でよくわからないことを色々されてるのがあんまり好きじゃないので standalone 版で使うだけでいいかなって気はしました
serve できない
とりあえずいくつかのテンプレートの初期状態を見てみようとしたのですが……default と simple は問題なく動いたのですが material テンプレートだけは serve ができません
こんなエラーが起きます
Setting up SSL certificate (may require sudo)...
Attempting to spawn simplehttp2server to generate cert.
Failed to generate dev SSL certificate: Error: spawn C:\Users\winuser\Desktop\33\mate\node_modules\simplehttp2server\vendor\simplehttp2server_windows_amd64.exe ENOENT
Falling back to shared directory + simplehttp2server.
(dir: C:\Users\winuser\AppData\Roaming\preact-cli)
server error> Error: spawn C:\Users\winuser\Desktop\33\mate\node_modules\simplehttp2server\vendor\simplehttp2server_windows_amd64.exe ENOENT
Error: spawn C:\Users\winuser\Desktop\33\mate\node_modules\simplehttp2server\vendor\simplehttp2server_windows_amd64.exe ENOENT
他では動いたのにと思って serve コマンドを見てみると default と simple では sirv を使っていました
どちらも serve コマンドの中身はこれです
preact build && sirv build --cors --single
https://github.com/preactjs-templates/default/blob/master/template/package.json
https://github.com/preactjs-templates/simple/blob/master/template/package.json
それに対して material の場合はこれです
preact build && preact serve
https://github.com/preactjs-templates/material/blob/master/template/package.json
普通に preact-cli の serve を使ってます
preact serve 自体がダメのようですね
対処する
フォルダが見つからない
まずは原因を調べようと思います最後に出てるエラーは ENOENT です
これはファイルやフォルダがみつからないってエラーです
preact-cli の serve では http2 サーバを作って serve するようで そのために simplehttp2server というツールを使っています
create のときの自動インストールでエラーでもあったのかなと見てみるとエラーが出ているパスにはちゃんと exe が存在しました
よくわからないのでとりあえず直接その exe を実行してみるとサーバが起動して普通にブラウザからアクセスして使えました
build だけして serve は別に手動でやってもよさそうです
ただ ちゃんと解決したいなとも思うので 続けて調べてみました
この exe を実行している箇所で引数を表示してみると cwd に 「ユーザフォルダ\AppData\Roaming\preact-cli」 を指定していました
しかし Roaming 以下に preact-cli フォルダはないのでこっちが見つからずエラーです
エラーを見ると実行するファイルのほうが無いように見えますが原因は cwd の方でした
わかりづらいですね
原因は preact-cli が自分で使うフォルダなのにフォルダを作ってないことのようです
手動でこのフォルダを作ったらそこのエラーはなくなりました
……が また別の問題が起きました
終わらない
実行したら途中で止まりますSetting up SSL certificate (may require sudo)...
Attempting to spawn simplehttp2server to generate cert.
このメッセージが出た状態でそこから進みません
もうサーバの起動が完了してるのかなとデフォルトポートの 8080 にアクセスしてもつながりませんでした
これが正常というわけではないようです
プロセスを見てみると simplehttp2server 自体は起動していました
ただ 「-listen 40210」 というオプションがついていて 8080 ではないです
どこから 40210 が出てきたんだろうと ソースを見ていると証明書作成処理で止まってるようです
https://github.com/preactjs/preact-cli/blob/v2.2.1/src/lib/ssl-cert.js#L28
さっきはなかったのにと思ったら 同じく cwd がなくてエラーなのでスキップしてたようです
よく見るとログに「Failed to generate dev SSL certificate:」というのもありました
わざわざ別の場所に証明書作らなくても直接 simplehttp2server を起動したら動いたので不要な処理に見えます
消してしまおうかとも思ったのですがせっかくあるのでこのまま動かそうと修正してみます
spawnServerForCert 関数を見ると色々実装がおかしいです
まず execFile のコールバック関数は実行が終わってから呼び出されるのに 実行中に呼び出される前提のようなコードです
simplehttp2server のプログラム自体は自動で終了しないので 標準出力から 「listening」 を受け取ると証明書作成は完了したとみなしてプロセスを kill しています
またタイムアウトのチェックのタイマーを開始したりしています
パット見だと良さそうですが これらの処理が実行されるのは simplehttp2server の処理が終わってからです
kill しないと終わらないのですから これらが実行されることはありません
書いた人が spawn などの関数と間違って使ってそうです
これを spawn に置き換えてコールバック関数ではなく返り値を使って同様の処理にすれば動きます
ただ 「listening」 を含むかのチェックに正規表現を使ってますが RegExp に match メソッドは存在しません
正しくは test です
ここも修正必要です
実際に実行されてるのはバンドル済みなのでこういう感じに修正しました
const spawnServerForCert = () => new Promise((resolve, reject) => {
let cwd = (0, _persistPath2.default)('preact-cli');
let child = (0, _child_process.spawn)(_simplehttp2server2.default, ['-listen', ':40210'], {
cwd,
encoding: 'utf8'
});
let check = (() => {
var _ref2 = _asyncToGenerator(function* (chunk) {
if (/listening/gi.test(chunk)) {
clearTimeout(timer);
child.kill();
resolve({
key: yield _fs2.default.readFile(_path2.default.resolve(cwd, 'key.pem'), 'utf-8'),
cert: yield _fs2.default.readFile(_path2.default.resolve(cwd, 'cert.pem'), 'utf-8'),
keyPath: _path2.default.resolve(cwd, 'key.pem'),
certPath: _path2.default.resolve(cwd, 'cert.pem')
});
}
});
return function check(_x) {
return _ref2.apply(this, arguments);
};
})();
child.on("error", err => {
reject(err);
});
let timer = setTimeout(() => {
reject('Error: certificate generation timed out.');
}, 5000);
child.stdout.on('data', check);
child.stderr.on('data', check);
});
ここを直して再実行したら
Setting up SSL certificate (may require sudo)...
Attempting to spawn simplehttp2server to generate cert.
Listening on https://localhost:8080...
正常ぽいメッセージです
「https://localhost:8080/」にアクセスしたらページが見れました
preact 関係とかそこそこ大きな規模のプロジェクトですし リリース前に厳し目のレビューやテストがありそうなイメージでしたがそうでもなさそうですね
3.0
開発中の最新版だと直ってるのかなと思ってみてみると 3.0 ではそもそも serve コマンドがなくなっていましたそれに合わせて ssl-cert.js ファイルもなくなってます
問題も多いし sirv とか別のツールつかえばいいじゃんとなったのでしょうか
serve 機能自体 デバッグ用ですし わざわざ作るほどじゃないと判断したのかもです
他ツール
ついでに他のツールで serve はどうやってるのか見てみるとreact の react-scripts と vue の vue-cli では webpack-dev-server でした
無難に webpack 任せでいいのかもしれませんね