Webフロントエンドを自学しているんだが、まぁ詰まる。
詰まる度に5セントもらってたら今頃大金持ちだぜ。

Visual StudioでTypeScriptなWebプロジェクトを作ってたんだが、index.htmlに書いた<a href>が動作しない。hrefで遷移できない。
相対パスで遷移先のhtmlを指定していたんだが、そもそもindex.htmlに入る方法がなんか特殊だったような気がしたからserver.tsを確認してみた。

これは、Webフロントエンドに挑んだ男たちの、苦難と煩悶、そして、希望の物語である。

①はじまり

みんな~!
server.ts(あるいはserver.js)の中身って、最初はこうなってるよね~?
え?なってない?
荷物をまとめて今すぐここから読み進めてください。

んで俺は、自動生成されたプロジェクトを眺めまくり
「トップにアクセスしたらこいつが走るんだな」
と推定し、ググった結果そうであることが分かったから指定したhtmlを読み込むようにしようと思った。

※2018/12/20追記
SPAならそもそも画面遷移とかしないんです。
でもまぁ勉強の証だからこのページは残しておく。

②第一次改造

参考サイト:勢いで始めてみるNode.js Webアプリ開発

※トップに「pages」なるフォルダを作成し、その中に「index.html」を配置した。

なったお( ^ω^)こうなったお( ^ω^)

javascriptの構文のグロテスクさにゲボ吐きながらも、これで晴れてindex.htmlに接続することがかなった。解説は今はしない。続きを読み進めてくれ。

③異変

index.htmlにhrefタグを入れて、そのリンクを踏む。

あれーおかしいね遷移しないね

④第二次改造

思った。このserver.tsって、全部のアクセスを集約してしまっているんじゃないだろうか。

つまり、どうURLを変えようが、トップレベルが同じであればもうindex.htmlの蟻地獄に引きずり込まれてしまうんじゃなかろうか。

ググった。なんてググったか忘れたけど、Qiitaにあたった。

参考サイト:ExpressなしでNode.jsで簡単なWebサーバを作ってみる、HTTPを学ぶ

このページで「webServer.js」のソースコードを眺めた。それはもう、呆れるほど眺めた。親の顔より長い時間みた。
そして、とても参考になった。加えて、この記事書いた人のコードは結構クソだなと思った。出直してこい。

で、書き換えた結果がこうなったお。

はい。
汎用性の高い書き方ではないと思うわ。ヘッダーとか全部一緒になっちまうし。
あと多分GET、POSTの聞き分けとかできるんじゃないだろか?サーバーって名乗ってるくらいだし。しかしまぁ取り敢えず今回は良いや。

テキストエディタかなんかに貼って、テキスト検索掛けながら読み進めてくれ。

よくわかる解説(ダミ声)

◆http.createServer req res

「req」と「res」はサーバーに対する「request」とそれに対する「response」・・・普通だな!

そいで「http.createServer」ちゃんは「req」を提供する代わりに、「res」の中身を詰めることを欲している。
reqの型は「http.IncomingMessage」、resの型は「http.ServerResponse」らしい。

http.createServerは「http.Server」のインスタンスを生成し、そいつには「listen」というメソッドが存在する。

Visual Studio使ってたから何とか分かったけど、マジで型は明示しちくり~。

◆url.parse(req.url).pathname

「req.url」っていうのが、リクエストされたURLのフルパスになるらしい。
それを「url.parse」っていうメソッドに渡すと、なにやら「URL」を表現するオブジェクト(構造体?)になるらしい。そいつの「pathname」プロパティから、「ルートを除外したパス」が取れるらしい。

例えば「https://news.yahoo.co.jp/pickup/6263196」からpathnameをとると「/pickup/6263196」が取れるんだと思う。(推測)(ガバ調査

トップは「/」になる。

◆fs.readFile

いわゆるfile system。ファイル読み込むだけ。ドキュメントはこれ

◆setHtmlResponse

自作の関数。htmlのパスを指定したらそいつを読み込んで、なんやかんやresにつめる。
なんかコールバックとか駆使すればもっとスマートにかけるんだろうか?javaScriptわかんない。
まぁいいや。コールバック自体が見づらいし。

つーか、この関数はcreateServerの外に出すべきか?
「res」変数への値の設定の仕方がキモい。なんかグローバル変数的だ。「http.ServerResponse」のインスタンスも受け取って、それに値を詰めて返す方が綺麗だな。
でも…まぁ調査みたいなもんだから大目に見ちくり。

参照透過性?なにそれ?ごめん俺幼女だからわかんない。

switch caseもなんか数が増えてくるとヤバそうだね。
MapとかDictionaryとかあるなら使えばいいかな。
それか…なんかデータのテーブルみたいな構造を使えなかったっけ?ググってすぐ出てこなかったから今は諦めるけど。

⑤おわり

あとは、指定されたURLにアクセスしたればいい。
さっきの例を踏まえ、例えばドメインが「唐澤.com」であった場合

「http://唐澤.com/TEST」にアクセスすれば「./pages/testPage.html」のファイルを参照して表示することができる。

index.htmlには

<a href=”TEST”>テストページ</a>

を置いておけば、ちゃんと動作してくれる。

終わりっ!閉廷!以上!皆解散!

君ももう帰っていいよ。

結論

やさしくない!Node.jsは優しくない!説明が足りてない!ググっても微妙な記事しか出てこない!

⑥第三次改造(追記)

帰さねえからなぁ?(豹変)

最終的にこうなった。以上。

解説は・・・いらんだろ!jsファイルに対応したりしただけ!
swith-caseをむりやり一行ずつにしたけど、しなくていいよ。俺の都合。
改良の余地はたくさんあるので第四次改造は君の手で切り裂いてくれ。