Node.jsの続きです。前回はfsモジュールを使ってHTMLファイルを表示しました。今回はここからCSS、JSファイルを読み込みたく。そのためにはルーティング設定が必要でした。それではいきましょう!
【目次】
- CSSとJSのファイルをリンク
- CSS、JSファイルを読み込む
- Node.jsサーバを起動(ファイルが読み込まれない!)
- ルーティング設定
- ルーティング設定を反映
- swich文でURLとファイルをルーティング
- サーバを起動(CSS、JSファイル読み込み成功!)
- コード全体
- 最後に
前回記事
※参考:【Node.js】fsモジュールでHTMLファイルを表示する - クモのようにコツコツと
Node.js / Expressを習得するためにやったことまとめ(随時更新)
qiita.com
CSSとJSのファイルをリンク
前回、fn
モジュールを使ってHTMLファイルを表示した。
HTMLコード
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>こんにちは、のおど・じぇいえす。</title> </head> <body> <section> <h1>こんにちは、のおど・じぇいえす。</h1> <p>Node.jsでHTMLタグを作れるのかテストですと。</p> </section> </body> </html>
JSコード
const http = require('http'); const fs = require('fs'); const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer((req, res) => { fs.readFile('./html/index.html', 'UTF-8', (error, data) => { res.writeHead(200, {'Content-Type': 'text/html'}); res.write(data); res.end(); }); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
詳細は前回記事を参照。
※参考:【Node.js】fsモジュールでHTMLファイルを表示する - クモのようにコツコツと
今回も掌田さんの「Node.js超入門」を参考に進める。
- 作者:津耶乃, 掌田
- 発売日: 2018/08/25
- メディア: 単行本
書籍では次にHTMLテンプレートエンジンのEJSに入るが、それは既に体験済みなので、その先のルーティング設定をやってみる。
CSS、JSファイルを読み込む
HTMLファイルだけだと寂しいのでCSSやJSのファイルを読み込んでみたい。
HTMLコード
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>こんにちは、のおど・じぇいえす。</title> <link rel="stylesheet" href="css/style.css"> <script src="js/script.js"></script> </head> <body> <section> <h1>こんにちは、のおど・じぇいえす。</h1> <p>Node.jsでHTMLタグを作れるのかテストですと。</p> </section> </body> </html>
head
タグの中でcssファイルとjsファイルを読み込む
CSSファイルを作る。
CSSコード
h1 { color: red; }
ほんとに簡易な内容。h1
タグを赤くするだけ。
JSファイルも作る。
alert("こんにちは、のおど・じぇいえす!");
JSも簡単に。アラートでハローワールド。
Node.jsサーバを起動(ファイルが読み込まれない!)
この状態でターミナルを立ち上げでcd
コマンドでフォルダに移動。
cd (ファイルパス)/node_test
Node.jsサーバを立ち上げる!
node node_test.js
サーバが起動するとターミナルにコンソールログが帰ってくる。
Server running at http://127.0.0.1:3000/
ブラウザでURLを開くが…
http://127.0.0.1:3000/
挙動は変わらない。
CSSスタイルが当たってないしアラートも立ち上がらない。index.htmlしか読み込まれていないということだ。
ルーティング設定
CSS、JSファイルを読み込ませるには「ルーティング設定」をする必要がある。
ネットワーク上で行われる道案内であり
通信において「あ~、君はそこに行きたいのか~。じゃあ、取りあえずそっちの道を行きなよ」と、データさんの行くべき道を示してくれる仕組みのこと
です。
※参考:https://wa3.i-3-i.info/word1498.html
const url = require('url');
まず、require()
メソッドでurl
オブジェクトを読み込む。
const server = http.createServer(RouteSetting);
変数server
のhttp.createServe()
の中の処理は長くなるので外部関数RouteSetting
にする。
RouteSetting
でルーティングの設定
function RouteSetting(req, res) { const url_parts = url.parse(req.url); switch (url_parts.pathname) { case '/': // '/'にアクセスした時の処理 break; case '/css/style.css': // cssファイルにアクセスした時の処理 break; case '/js/script.js': // jsファイルにアクセスした時の処理 break; } }
- 関数
RouteSetting()
を定義。引数は左からリクエストreq
、レスポンスres
- 変数
url_parts
でurl.parse()
メソッドでリクエストのURLをオブジェクトに変換する - switch文の条件は
url_parts
のpathname
index.html、cssファイル、jsファイルにアクセスがあった時の設定を書く
パースとはJSONをオブジェクト形式に変換すること。
※参考:REST APIとは何かを調べまくったらようやくイメージができてきたのでまとめた - クモのようにコツコツと
Swich文はif文のような分岐の書き方。並列条件でif文と違って書き順の影響を受けない。
※参考:【JSの基本-後編】書ける前に読む!HTML、CSS、JSの書式-5 - クモのようにコツコツと
※2021/04/01追記
レンさんよりコメントをいただきまして、今のNode.jsのバージョンではurl.parse()
ではなくnew URL()
で書く方法が推奨されているようです。(脆弱性のアラートが出る)
※参考:[Node.js] 新旧APIでのURLパースの違い - Qiita
ルーティング設定を反映
前回のコードにルーティング設定を追加していく。
JSコード
const http = require('http'); const fs = require('fs'); const url = require('url');
最初にrequire()
でhttp
、fs
、url
を読み込む。変数名も同じ。
const indexPage = fs.readFileSync('./html/index.html', 'UTF-8'); const styleCss = fs.readFileSync('./html/css/style.css', 'UTF-8'); const scriptJs = fs.readFileSync('./html/js/script.js', 'UTF-8');
次にfs.readFileSync()
でhtml、css、jsファイルを読み込む。変数名はindexPage
、styleCss
、scriptJs
。
前回のreadFile()
メソッドだとうまく動かず 、readFileSync()
メソッドで読み込む必要があった。2つの違いは非同期処理か同期処理か。
- readFile():非同期処理
- readFileSync():同期処理
まよったらreadFileSyncを使う
Node.jsをはじめたばかりで「同期?非同期?」な人は、とりあえず、fs.readFileSyncを使うのが無難です。
とのこと!
※参考:https://www.tech-tech.xyz/nodejs-readfile-readfilesync.html
そのあとはhttp.createServer()
の中をRouteSetting()
に外部関数化する以外は変わらない。
const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer(RouteSetting); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
swich文でURLとファイルをルーティング
で、本丸。RouteSetting()
関数の定義!URLとファイルと紐付けていく。
function RouteSetting(req, res) { const url_parts = url.parse(req.url); switch (url_parts.pathname) {
以下、swich文の中身。caseを追加していく。
一つ目はHTMLファイルの条件。
case '/': case '/index.html': res.writeHead(200, {'Content-Type': 'text/html'}); res.write(indexPage); res.end(); break;
今回初めて知ったんだが、caseを二つ連ねると処理に対して条件を複数設定できるようだ!
※参考:複数のcaseで同じ処理を実行 - 条件分岐 - C言語 入門
/
またはindex.html
ならば、という条件にした。
res.writeHead()
のContent-Type
はext/html
。
res.write()
の引数はindexPage
のhtmlファイル。
次はCSSファイルの設定。
case '/css/style.css': res.writeHead(200, {'Content-Type': 'text/css'}); res.write(styleCss); res.end(); break;
style.css
ならばという条件でres.writeHead()
のContent-Type
はtext/css
にする。
※参考:node.js css読み込み | ゴンの気まぐれなるままに
res.write()
の引数はstyleCss
のcssファイル。
三つ目はjsファイル。
case '/js/script.js': res.writeHead(200, {'Content-Type': 'text/plain'}); res.write(scriptJs); res.end(); break;
script.js
ならば、という条件でres.writeHead()
のContent-Type
はtext/plain
。「js」じゃないんだな。
※参考:node.js html内のjsファイルの読み込み | ゴンの気まぐれなるままに
res.write()
の引数はscriptJs
のjsファイル。
最後はdefault
でelse
(さもなくば)的な設定。
default: res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('お探しのページは見つかりません。'); break; } }
上記のどれにも当てはまらない場合は「お探しのページは見つかりません。」というテキストを表示。
(2020/08/15追記)
上記の書き方だと日本語が文字化けになったため、下記の記事で書き換えてみた。
※参考:【Node.js】ルーティング設定で複数ページを表示する - クモのようにコツコツと
サーバを起動(CSS、JSファイル読み込み成功!)
リベンジでサーバ起動!
node node_test.js
起動成功!
http://127.0.0.1:3000/
ブラウザを開くと、お、アラートが立ち上がった!
アラートを閉じると、見出しが赤くなってる!
コード全体
最終的にこうなった。
const http = require('http'); const fs = require('fs'); const url = require('url'); const indexPage = fs.readFileSync('./html/index.html', 'UTF-8'); const otherPage = fs.readFileSync('./html/other.html', 'UTF-8'); const styleCss = fs.readFileSync('./html/css/style.css', 'UTF-8'); const scriptJs = fs.readFileSync('./html/js/script.js', 'UTF-8'); const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer(RouteSetting); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); }); function RouteSetting(req, res) { const url_parts = url.parse(req.url); switch (url_parts.pathname) { case '/': case '/index.html': res.writeHead(200, {'Content-Type': 'text/html'}); res.write(indexPage); res.end(); break; case '/css/style.css': res.writeHead(200, {'Content-Type': 'text/css'}); res.write(styleCss); res.end(); break; case '/js/script.js': res.writeHead(200, {'Content-Type': 'text/plain'}); res.write(scriptJs); res.end(); break; default: res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('お探しのページは見つかりません。'); break; } }
最後に
ということで、CSS、JSファイルを読み込むことに成功しました。フロントエンドに慣れていると、ルーティング設定をしないとファイルが読み込まれないのはちょっと手間に感じる。
しかし、逆に、全然違う場所にあるファイルもルーティング設定によって自分の思い通りの構成に設定することもできる。
テンプレートエンジンを使っていくとページのパーツや値を組み合わせてサイトと作ることができる。バックエンドのメリットをだんだんと感じていきたい。
次回は引き続きルーティング設定で複数ページのサイトと作ってみたく。それではまた!
Node.js / Expressを習得するためにやったことまとめ(随時更新)
qiita.com