クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【Node.js】fsモジュールでHTMLファイルを表示する

Node.jsの続きです。前回はハローワールドを打ち替えてHTML形式で表示しました。今回はfsモジュールでHTMLファイルを表示します。それでは行きましょう!

【目次】

前回記事
※参考:【Node.js】ハローワールドの打ち替え(ポート番号、日本語化、HTMLタグ化) - クモのようにコツコツと

Node.js / Expressを習得するためにやったことまとめ(随時更新)
qiita.com

前回のおさらい

前回、write()メソッドの中で改行を入れたらエラーになったため、断腸の思いでひと繋がりのタグにした。

f:id:idr_zz:20200302070201j:plain

JSコード

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
  //res.setHeader('Content-Type', 'text/plain');
  res.write('<section><h1>こんにちは、のおど・じぇいえす。</h1><p>Node.jsでHTMLタグを作れるのかテストですと。</p></section>');
  res.end();
  //res.end('Hello Node.js!');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

この部分ね。

  res.write('<section><h1>こんにちは、のおど・じぇいえす。</h1><p>Node.jsでHTMLタグを作れるのかテストですと。</p></section>');

ちょっと可読性が低い。このまま書き続けてもどんどん肥大化していくことが想像できる。。

※参考:【Node.js】ハローワールドの打ち替え(ポート番号、日本語化、HTMLタグ化) - クモのようにコツコツと

write()メソッドでの複数行表現!

掌田さんの「超入門」シリーズ(←Vue、Reactの習得でお世話になった)にNode.js編もあった!EJS、Express、MySQLのDBが触れられている。こちらを参考に進める*1

Node.js超入門[第2版]

Node.js超入門[第2版]

そしてこの「Node.js超入門」の中に、write()メソッドでHTMLタグを複数行で表現する方法があった!

こんな感じに。 JSコード

  res.write('<!DOCTYPE HTML>');
  res.write('<html>');
  res.write('<head>');
  res.write('<meta charset="utf-8">');
  res.write('<title>こんにちは、のおど・じぇいえす。</title>');
  res.write('</head>');
  res.write('<body>');
  res.write('<section>');
  res.write('<h1>こんにちは、のおど・じぇいえす。</h1>');
  res.write('<p>Node.jsでHTMLタグを作れるのかテストですと。</p>');
  res.write('</section>');
  res.write('</body>');
  res.write('</html>');

ちょっと見た目はうるさいけどこれなら可読性は保てる。DOCTYPE宣言、htmlタグ、headタグ、bodyタグなども書いてみた。

サーバ起動!

node node_test.js

Consoleは帰ってきている。成功だ。エラーにならない!

Server running at http://127.0.0.1:3000/

ブラウザで見てみる。

http://127.0.0.1:3000/

うむ、表示される! f:id:idr_zz:20200312065429j:plain

気になるソースコードは… f:id:idr_zz:20200312073749j:plain Oh、なるほど。ソース上では改行は無視されるわけか。まあでもheadタグとかもここに反映されてはいる。

  • writhe()メソッドはいくつでも分けて実行できることはわかった
  • writhe()メソッドを分けるとHTMLの改行は見えやすくなる
  • しかし書き出されたソースには改行は反映されない
  • 見た目もうるさいのでやはりここにコンテンツを書いていくのは肥大化につながると思う

ということでHTMLファイルを外部においてこれを表示したい。

HTMLファイルを作る

htmlというフォルダを作成。さらにその中にindex.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>

先程のwrite()メソッドの中身をここに配置。ふー、スッキリしてる。

fsモジュールでHTMLファイルを読み込む

Node.jsでファイルを読み込むのはfsというモジュールを使うようだ。fsは「File System」の略なんだね。

※参考:File system | Node.js v14.8.0 Documentation

まず、require()メソッドでfsモジュールを読み込む。

const fs = require('fs');

ファイルの読み込みはreadFile()メソッドで行う。

fs.readFile(ファイルのパス, 文字コード, コールバック関数)

※参考:【Node.js入門】fsモジュールでファイルの読み書き方法まとめ | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト

実際に書いてみる。

  fs.readFile('./html/index.html', 'UTF-8',
  (error, data) => {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write(data);
    res.end();
  });
  • fsモジュールのreadFile()メソッド実行、第1引数はindex.htmlのパス、第2引数は文字コードUTF-8
  • readFile()メソッドの第3引数は無名関数、無名関数の第1引数はerror、第2引数はdata
  • reswriteHead()メソッド、第1引数はステータスコード200、第2引数は連想配列でContent-Typeキーの値はtext/html
  • reswrite()メソッドの引数はdata
  • resend()メソッド

前回と色々な値の書き方、場所が変わっている。

文字コードはsetHeader()メソッドではなくreadFile()メソッドの第2引数になった。そしてsetHeader()メソッド自体もwriteHead()メソッドになった。

ステータスコードはstatusCodeプロパティ ではなくwriteHead()メソッドの第1引数になった。

res.write()メソッドはdataを読み込むだけなのでとてもコンパクト!

ブラウザ表示確認

先程のコードの全体はこうなる。

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}/`);
});

ちゃんと動くか確認する!

まずサーバを「Contrl + C」で一旦閉じる。

サーバ起動!

node node_test.js

ブラウザ表示を確かめる。

http://127.0.0.1:3000/

f:id:idr_zz:20200312065429j:plain おお、ちゃんと表示される。

index.html/htmlフォルダの中にあるのだが、直下のパスとして表示されている!

気になるソースコードは…
f:id:idr_zz:20200312073808j:plain よし!ちゃんと改行されている。index.htmlが読み込まれているということだ!

外部関数として読み込む

外部関数にして読み込んでもいいようだ。

const server = http.createServer((req, res) => {
  fs.readFile('./html/index.html', 'UTF-8', readHTML);

  function readHTML(error, data) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write(data);
    res.end();
  }

});
  • readHTML()関数を作ってreadFile()の第3引数で読み込む

※参考:【Node.js】 htmlファイルを読み込んで画面を表示しよう。 – web.lab

こっちの方がスッキリしていい。ただ、アロー関数だとエラーになるようだったのでfunction宣言した。

最後に

ということで、fsモジュールでindex.htmlファイルを読み込むことができました!

次にやってみたいのは、ここからcss、jsのファイルを読み込んだり、別ページのリンクを開いたり。調べている限り、一筋縄ではいかず「ルーティング」の設定が必要?次回、トライします。それではまた!


Node.js / Expressを習得するためにやったことまとめ(随時更新)
qiita.com

*1:2014年からの積読「Node.js実践プログラミング」を最近ようやく読了したのだが最近の内容も抑えておきたく2冊目として購入した