node.js、express、handlebarsを使ってウェブサーバーの立ち上げからページの制作までをやってみた - 2

#次はNode環境で、ウェブサイトを作っていこう 
[前回](https://qiita.com/monsoonTropicalBird/items/fe51c431d1abbc68ff7c)からの続き、expressをインストールし、サーバーも立ち上がったので、早速ウェブサイトを作っていくよ。 
通常のサイト制作と大きく違っているのは、まず、ディレクトリの構造。 前回もやったけど、エンドポイントって考え方がメインになるので、旧来の絶対パスとか相対パスっていう考え方とはちがうなぁという感じ。 
基本、静的データと動的データを分けて、expressに登録していくんじゃ。
あと、テンプレートエンジンと言われているプラグインをexpressに入れて、ページを作っていくよ。 
何故そんなものを使うかと言うと、ただの静的なサイトをテキストエディタでもIDEでも使って作って登録した静的フォルダにいれれば、今までのような阿部 寛的なページは勿論作れるのじゃが、php的な作り方。つまり、ヘッダーとかフッタとかの使い回す部分を分けておいて、ページ読み込み時に合体させるみたいな事をするには、このテンプレートエンジンを使うのじゃ。 
名前の通り、”テンプレート”を生成するエンジンじゃの。 
色々種類はあるが、自分はhandlebarsが使いやすいので、これで解説するぞ。いいな！ 
handlebarsではなくて、それのexpress用エンジン[hbs](https://www.npmjs.com/package/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ページとか。 
![Screenshot from 2021-06-23 02-48-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1204968/5f510622-dda9-8563-5281-0b047717e555.png) 
それが出来たら、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***を作ろう。ここがランディングページになる。
![Screenshot from 2021-06-23 02-15-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1204968/94db998e-11cc-b251-c39c-36bae62de0b0.png)
hbsって言っても、普通のhtmlページ。

```html:index.hbs
<!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/　にアクセスすると、ページが表示されてるね。 
次は、少し動的に、ページのタイトルとサイトの説明文を挿入してみよう。 
{{}}で囲ったところに、変数を入れると、レンダリング時に表示される。

```html:index.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>

    <body>
<h1>{{title}}</h1>
<h3>{{description}}</h3>
    </body>

</html>

```

```Javascript:app.js
app.get('/',(req, res)=>{
res.render('index', {
    title: "Hishori Abe no site",
    description: "Welcome to fastest site in japan"
})
})
```
で、ブラウザでローカルにアクセスし、表示するとこうなってるはず。 
![Screenshot from 2021-06-23 02-42-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1204968/957fb925-3949-6f1a-ade9-1809c6a8324e.png)
ここまでで、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に分けて保存。 
![Screenshot from 2021-06-26 01-40-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1204968/48193780-71d4-51d6-253e-f4c2d5f00ef9.png)

こうすると、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ファイルを作り、そこにペースト。 

```: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>
```
で、{{>ファイルの名前}}でターゲットに挿入。

```:index.hbs
{{>header}}

    <body>
<h1>{{title}}</h1>
<h3>{{description}}</h3>
<h2>test</h2>
    </body>

</html>
```

index.hbsをローカルで開いた結果。

![Screenshot from 2021-06-26 02-05-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1204968/b99984dd-d908-4893-29ac-acdcef4e9d6d.png) 
ちゃんと表示されてるね。 
これでナビでもフッタでも、共通部分のファイルを作って、{{>ファイルの名前}}で読み込めばオケ。


ここまでのapp.jsファイル 

```: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}`);
})
```
[次回](https://qiita.com/monsoonTropicalBird/items/015112aa8ae25b973d49)はこれをサーバーにアップするよ。