#次はNode環境で、ウェブサイトを作っていこう
前回からの続き、expressをインストールし、サーバーも立ち上がったので、早速ウェブサイトを作っていくよ。
通常のサイト制作と大きく違っているのは、まず、ディレクトリの構造。 前回もやったけど、エンドポイントって考え方がメインになるので、旧来の絶対パスとか相対パスっていう考え方とはちがうなぁという感じ。
基本、静的データと動的データを分けて、expressに登録していくんじゃ。
あと、テンプレートエンジンと言われているプラグインをexpressに入れて、ページを作っていくよ。
何故そんなものを使うかと言うと、ただの静的なサイトをテキストエディタでもIDEでも使って作って登録した静的フォルダにいれれば、今までのような阿部 寛的なページは勿論作れるのじゃが、php的な作り方。つまり、ヘッダーとかフッタとかの使い回す部分を分けておいて、ページ読み込み時に合体させるみたいな事をするには、このテンプレートエンジンを使うのじゃ。
名前の通り、”テンプレート”を生成するエンジンじゃの。
色々種類はあるが、自分はhandlebarsが使いやすいので、これで解説するぞ。いいな!
handlebarsではなくて、それのexpress用エンジンhbsをインストール。
~/myProject/web-server$ npm i hbs
up to date, audited 89 packages in 2s
2 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
そして、expressにテンプレートエンジンとして登録。
app.set('view engine', 'hbs');
次に、publicディレクトリを制作。
ここに静的なファイルは保存していく。img,css,クライアント側jsなんかじゃな。あと、岩のようなhtmlページとか。
それが出来たら、publicディレクトリをexpressに登録。
その前に、pathモジュールをダンロードして、インストール。
npm i path
const path = require('path');
nodeのサイトは、app.jsが全ての起点になるのと、サーバーにデプロイする際に、ディレクトリの構造が従来のサイト構造と違っているので、app.jsファイルを基点にモジュールでパスをしっかりと確定しておかないとややこしい事になる。なので、モジュールで指定する。
const publicDir = path.join(__dirname, "../public")
app.use(express.static(publicDir));
何をやっているかと言うと、ルートフォルダからのpublicディレクトリへのパスをモジュールで割り出して、expressで静的ディレクトリとして登録している。静的なファイルは全部ここやでとexpressに伝えている。
そして、viewsディレクトリを作る。テンプレートエンジンで制作したページは、基本ここに保存していくのである。
静的ファイルはpublic、動的ファイルはviews、nodeのローレベルファイルはルート直下っていうイメージでディレクトリを整理していくと良いよ。多分!
で、その中にindex.hbsを作ろう。ここがランディングページになる。
hbsって言っても、普通のhtmlページ。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Node de Site</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Title here</h1>
</body>
</html>
で、前回やったルーティング。
このindex.hbsをルートページにする。sendでなくて、render。テンプレートをレンダリングする。
app.get('',(req, res)=>{
res.render('index')
})
で、一度サーバーを立ち上げて、ページを表示させてみよう。
~/myProject$ node src/app.js
server running on Port:3030
ブラウザで localhost:3030/ にアクセスすると、ページが表示されてるね。
次は、少し動的に、ページのタイトルとサイトの説明文を挿入してみよう。
{{}}で囲ったところに、変数を入れると、レンダリング時に表示される。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title here</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>{{title}}</h1>
<h3>{{description}}</h3>
</body>
</html>
app.get('/',(req, res)=>{
res.render('index', {
title: "Hishori Abe no site",
description: "Welcome to fastest site in japan"
})
})
で、ブラウザでローカルにアクセスし、表示するとこうなってるはず。
ここまでで、node環境にexpressをインストールし、handlebarsを使って、htmlページをサーバー上で表示することが出来たんじゃ。
app.jsファイルはこんな感じ。
const path = require('path');
const express = require('express');
const app = express();
const port = process.env.PORT || 3030;
app.set('view engine', 'hbs');
app.get('/',(req, res)=>{
res.render('index', {
title: "Hishori Abe no site",
description: "Welcome to fastest site in japan"
})
})
const publicDir = path.join(__dirname, "../public")
app.use(express.static(publicDir));
// routing
// / => root
app.get('/', (req, res)=>{
res.send('Hello Express!');
})
app.listen(port, ()=>{
console.log(`server running on Port:${port}`);
})
バイトの時間がきたんで、handlebarsを使ってページをテンプレート化していくのは次回じゃ!
じゃあの。
###[追記]hbsを使って、ウェブページのテンプレート化
時間が出来たので、追記じゃ。phpでやるような、ヘッダやフッタなんかのサイトで使い回すパーツを分けて保存し、それをレンダリング時に合体させるというアレを、hbsを使って.hbsファイルでやってみようと思うのじゃ。
で、次回はお待ちかねのサーバーアップで、wwwに公開するのじゃ!
初めの方で、動的ファイルの保存場所として、viewsフォルダを作ったと思うのだが、この名前はexpressの中で決まっていて、expressはrenderする為に、いわゆるhtmlのソースをこの中から探そうとする。
今回はページをテンプレート化するので、整理しやすいようにtemplateファルダを作り、メインのソースページとテンプレート部品をviewsとpartialsに分けて保存。
こうすると、expressにこのフォルダがviewsだよと、教えてあげないといけない。
const viewsPath = path.join(__dirname, "../templates/views")
app.set('views', viewsPath);
やっている事は、前回のように、app.jsを基点に、templateファルダへのパスを設定。
で、expressにviewsとして設定。このtemplateがviewsって事を伝えてる。
その次は、部品用のpartialsディレクトリを作り、hbsに、ここに部品が入ってるよという事を伝えないといけない。
hbsモジュールをapp.jsファイルに追加。
const hbs = require('hbs');
下記コードで設定完了。
const partialPath = path.join(__dirname, "../templates/partials")
hbs.registerPartials(partialPath);
試しに、index.hbsからヘッダー部分をカットして、header.hbsファイルを作り、そこにペースト。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title here</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
で、{{>ファイルの名前}}でターゲットに挿入。
{{>header}}
<body>
<h1>{{title}}</h1>
<h3>{{description}}</h3>
<h2>test</h2>
</body>
</html>
index.hbsをローカルで開いた結果。
ちゃんと表示されてるね。
これでナビでもフッタでも、共通部分のファイルを作って、{{>ファイルの名前}}で読み込めばオケ。
ここまでのapp.jsファイル
const path = require('path');
const express = require('express');
const hbs = require('hbs');
const { send } = require('process');
const app = express();
const port = process.env.PORT || 3030;
// define path for express
const publicDir = path.join(__dirname, "../public")
const viewsPath = path.join(__dirname, "../templates/views")
const partialPath = path.join(__dirname, "../templates/partials")
// set-up handlebars engine and path to views
app.set('view engine', 'hbs');
app.set('views', viewsPath);
hbs.registerPartials(partialPath);
// set-up static directory to serve
app.use(express.static(publicDir));
// routing
// / => root
app.get('/',(req, res)=>{
res.render('index')
})
app.get('*', (req, res)=>{
res.send('404 not found!')
})
app.listen(port, ()=>{
console.log(`server running on Port:${port}`);
})
次回はこれをサーバーにアップするよ。