入門!Expressのインストールと基本のまとめ

こんにちは❗フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、これまでこのブログではLaravelVueの記事を多く公開してきましたが、この度「より高速に動くサイト」を開発する可能性が出てきたので、これまで虎視眈々と狙っていたNode.jsのフレームワーク「Express」も少しずつ記事として紹介していけたらな、と考えています。(といってもメインは大好きなLaravelで不動ですが😊)

そこで!

今回は、まずはExpressをインストールする方法と、さらに、Expressを使う基本的な内容をまとめてみることにしました。

ぜひ皆さんのお役に立てると嬉しいです。

開発環境: Node.js 8.10、Ubuntu 18.04、nginx 1.14

フォルダを用意する

まずExpressをインストールするフォルダをつくります。

※ フォルダ名はお好みで変更してください。

Expressをインストールする

ターミナルで先ほど作成したフォルダに(cdコマンドで)移動し、以下のコマンドを実行してnpmを初期化します。

npm init

※ 色々と質問されますが、めんどうな場合はEnterキー連打で終了させるか-yをつけて質問をスキップしてください。

次にExpressの本体をインストールします。

npm install express --save

インストールが完了するとフォルダ内は、次のようになります。

ウェブサーバー用のコードをつくる

続いて、ブラウザからExpressにアクセスできるようにウェブサーバーが起動できるようにしましょう。

まずは、「package.json」を開いて「scripts > start」の部分を以下のように書き換えてください。

{
  "name": "express41",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodejs app.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  }
}

注意:Ubuntuの場合Node.jsのコマンドはnodeではなくnodejsです。もしnodeで実行したい場合は、以下のコマンドでシンボリックリンクを作っておくといいでしょう。

sudo ln -s "$(which nodejs)" /usr/bin/node

続いて、同じフォルダ内に「app.js」を作成し中身を以下のようにします。

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('うまく動いてます!');
});

// 5000番ポートで待機
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`${PORT}番のポートで待機中です...`);
});

続いて、以下のコマンドを実行してnpmを起動します。

npm start

すると、以下のような表示になります。

これで、ウェブサーバーの設定は完了です。

では、実際にブラウザから「http://localhost:5000」にアクセスしてみましょう。

独自ドメインをつかう

もちろんこのまま開発を進めてもいいでしょうが、「localhost:5000」では開発するサイトが増えてくると、どれがどのサイトかわからなくなってしまいます。

そこで、今回は「http://express41.test」にアクセスすると、今回作ったExpressアプリが実行できるようにしてみましょう。

まず、「/etc/nginx/sites-available/default」を開いて以下のコードを追加して保存します。

server {
    listen 80;
    server_name express41.test;
    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $remote_addr;
     }
}

【追記:2020.02.04】IPアドレスを取得するために最後の行を追加しました。これがないと全てローカルからの接続になるので「::ffff:127.0.0.1」になってしまいます。なおIPアドレスを取得するには以下のようにします。

const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

保存したらnginxを再起動してください。

sudo systemctl restart nginx

次に「express41.test」がローカルに向くようにします。

※ ここからは「windows 10編」と「Ubuntu 18.04編」に別れます。ご自身の環境に合わせて読み進めてください。(・・・といっても、ほとんどwin 10だと思いますが😅)

Windows 10編

まず、検索ボックスに「notepad」と入力してメモ帳を表示させます。

そのままクリックせず、右クリックをして「管理者として実行」をクリック。

確認のポップアップが表示されるので「はい」をクリック。

メモ帳が起動するので、「ファイル > 開く」をクリック。

c:\Windows\System32\Drivers\etc」を選択 すると(おそらく)何も表示されないので、右下の表示ファイルタイプを「すべてのファイル」に変更し、「hosts」を開く。

最終行に「127.0.0.1 express41.test」を追加して保存する。

Ubuntu編

以下のコマンドを実行します。

sudo gedit /etc/hosts

テキストエディタが開くので、

127.0.1.1	express41.test

を追加して保存してください。

ブラウザで確かめる

では、ブラウザから「http://express41.test」にアクセスしてみましょう。

直接アクセスできる「public」フォルダをつくる

例えば、画像やHTMLCSS、(ブラウザ側の)JSファイルに直接アクセスできるようにしてみましょう。

今回は以下の画像を使います。(神戸ポートタワー近くに展示されているクリスタル・ピアノです😊)

では、まずは「/public/images」フォルダをつくって、そこに「crystal_piano.jpg」を設置します。

次に、「app.js」で「public」フォルダに直接アクセスできるよう以下のコードを追加します。

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('うまく動いてます!');
});

// ここ↓↓↓
app.use(express.static('public'));

// 5000番ポートで待機
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`${PORT}番のポートで待機中です...`);
});

注意:ここで注意が必要なのが、「app.js」に変更を加えた場合は必ずnpmを再起動しないといけいないということです。

つまり、「Ctrl+C」などでストップしてもう一度以下のコマンドを実行しないと変更箇所が反映されません。

npm start

これで、「http://express41.test/images/crystal_piano.jpg」にアクセスすると、「public/images/crystal_piano.jpg」の画像が表示されることになります。(URLにはpublicは不要ですので注意してください)

データベースにアクセスする

今回はexpress41という名前のデータベースをMySQLで用意して、そこからデータを管理できるようにします。

まずは、以下のコマンドでmysqlのパッケージをインストールしましょう。

npm install mysql

インストールが完了したら、MySQLにデータベースを作り、テストとしてusersというテーブルをつくります。

※ なお、DBの文字コードはLaravelと同じく utf8mb4_unicode_ciを使っています。

また、テスト用に以下のようなユーザーデータも追加しておきます。

続いて、このデータベースにアクセスできるようルートフォルダに「db.js」というファイルを作成し、中身を以下のようにしてください。

const mysql = require('mysql');
const db = mysql.createConnection({
    host     : '127.0.0.1',
    user     : 'root',       // DB接続ユーザー
    password : '**********', // DB接続パスワード
    database : 'express41'
});

db.connect(err => {

    if(err) { // DBの接続に失敗

      throw err;

    };

});

module.exports = db;

では、「app.js」に戻ってusersテーブルからデータを取得してみましょう。(太字が追加した部分です)

const express = require('express');
const app = express();
const db = require('./db');

app.get('/', (req, res) => {

  const sql = 'SELECT * FROM users';
  db.query(sql, (err, rows) => {

    if(rows.length > 0) { // データが見つかった場合

      res.send(rows);

    } else {

      res.send('データが見つかりません。');

    }

  });

});

// 省略

この状態で「http://express41.test」にアクセスすると、以下のようにDBデータがJSON形式で表示されることになります。

[{"id":1,"name":"太郎","email":"taro@example.com"},(省略)}]

テンプレート・エンジンをつかう

Expressは多数のテンプレート・エンジンをサポートしていますが、今回はLaravelBladeに近いmustache.jsを使うことにします。

まずは、以下のコマンドでパッケージをインストールしてください。

npm install mustache-express --save

次に、「app.js」でテンプレート・エンジンの設定をします。

const express = require('express');
const app = express();
const db = require('./db');

// テンプレート
const mustacheExpress = require('mustache-express');
app.engine('mst', mustacheExpress());
app.set('view engine', 'mst');
app.set('views', __dirname + '/views');

app.get('/', (req, res) => {

  res.render('index', {
    title: 'ページタイトル',
    message: 'テストメッセージ'
  });

});

// 省略

これで、viewsフォルダの中にある.mstという拡張子がついたファイルがテンプレートとして使えるようになりました。

/views/index.mst」を作成して中身を次のようにしてください。

<!DOCTYPE HTML>
<html>
<head>
  <title>{{ title }}</title>
</head>
<body>
  <div>
    {{ message }}
  </div>
</body>
</html>

では、この状態でもう一度「npm start」を使って再起動してブラウザから見てみましょう。

配列をループする

mustache.jsで配列をループするには、まず配列をパラメータとしてセットします。

res.render('index', {
    numbers: [1, 2, 3, 4, 5]
});

そして、テンプレート・ファイルの方で以下のようにするとループすることができます。

{{ #numbers }}
    <ul>
      <li>{{ . }}</li>
    </ul>
{{ /numbers }}

コレクションをループする

mustache.jsでオブジェクトが配列としてまとまった、いわゆる「コレクション」をループするには次のようにします。

まずは、パラメータとしてセットします。

res.render('index', {
    users: [
        {name: '名前1', email: 'test1@example.com'},
        {name: '名前2', email: 'test2@example.com'},
        {name: '名前3', email: 'test2@example.com'},
    ]
});

テンプレートの中でのループはこのようになります。

{{ #users }}
<ul>
    <li>{{ name }}: {{ email }}</li>
</ul>
{{ /users }}

実行結果です。

ルートを分割する

ここまででは、「app.js」内にルートを作って実行してきましたが、開発を進めていく上で、さすがに全てのルートを同じファイル内に書いてしまうと、どこに何があるかが分かりにくくなってしまうので、ルートを分割する方法をご紹介します。

まず、「routes」というフォルダをつくり、その中に「users.js」というファイルを作成します。

そして、中身は以下のようにしてください。

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {

  res.send('「users」の一覧ページ');

});
router.get('/:id', (req, res) => {

  res.send('「users」の個別ページ');

});

module.exports = router;

続いて、「app.js」で以下のように設定します。

// ルート
app.use('/users', require('./routes/users'));

では、npmを再起動してブラウザで確認してみましょう。

この方法を応用すればミドルウェアを使って、/users階層は要ログインにすることもできます。

ちなみに:idの値を取得したい場合は以下のようにすればOKです。

router.use(express.json());
router.use(express.urlencoded({ extended: true }));

router.get('/:id', (req, res) => {
  const userId = req.params.id;

});

おわりに

ということで、今回は新たな試みとしてNode.jsのフレームワークExpressを使って基本的な内容をまとめてみました。

ちなみに、初めて本格的にExpressを使ってみた雑感ですが、やはり「いかにLaravelが便利機能をたくさん持っているか」を実感しました。

というのも、LaravelだとDBテーブルを管理するマイグレーションが標準搭載していますし、ログイン機能も(最近パッケージとして分離されましたが)最初から存在しています。また、DBモデル(Eloquent)のようなものがExpressにはないので、これも自前で実装するかパッケージを使う、もしくはSQL文を直に書く必要があります。

となると、やはり保守管理や開発スピードを考えるとLaravelの方が優位かなと感じています。(Express初心者なので重要な部分が抜けている可能性は高いですが・・・)

また、Node.jsの一番の欠点は「エラーが発生すると、サーバーが落ちる」。これにつきます😫(ただし、この点に関しては解決する方法もあるそうなので、今後掘り下げて調査していこうかと考えています)

ただ、やっぱり実行スピードの高速化というのはとても大きな魅力なので、もう少し使ってみようなかなという感じです。

皆さんもぜひExpressにチェレンジしてみてくださいね。

ではでは〜!

「遅れましたが、新年あけましておめでとうございます。
本年も「Console dot Log」をよろしくお願いいたします。m_ _m✨」

開発のご依頼お待ちしております 😊✨
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします!
このエントリーをはてなブックマークに追加       follow us in feedly  

開発効率を上げるための機材・まとめ