iPX社員によるブログ

iPX社員が"社の動向"から"自身の知見や趣味"、"セミナーなどのおすすめ情報"に至るまで幅広い話題を投下していくブログ。社の雰囲気を感じ取っていただけたら幸いです。

Node.js+Expressの学習メーモ

Node.js+Expressの学習

久しぶりにブログを投票することになりました。EPLUのパルハットです。
最近自分が関わった業務でJavaScriptをベースにした開発が幾つかがありました。
今回自分の勉強も重ねて、JavaScriptのサーバサイドプログラムであるNode.jsとそのフレームワークExpress.jsを使って、
前回Djangoで作ったブログと同じ機能のものを作っていきたいと思いました。

環境と設定

  1. Node.js
  2. Express.js
  3. monent: Date,Timeオブジェクトの表示フォマットを変更可能
  4. express-generator

開発環境の簡単構築のためにExpress Application Generator
ツールを使用します。

詳しい環境設定と必要なモジュールのインストールの説明は避けます。

express generatorのインストール

コマンド: npm install express-generator -g

新規のExpress ApplicationをExpress-blog名で作成

コマンド: express express-blog --view=pug

以下のフォルダ構成が作成される。

f:id:ipx-writer:20181004173521p:plain

nodemonのインストール。サーバ再起動なしで、Webブラウザの自動更新を可能にします。

コマンド: npm install --save-dev nodemon

package.jsonの中身み確認します。
"scripts": {
        "start": "node ./bin/www",
        "devstart": "nodemon ./bin/www"
    },
    "devDependencies": {
        "nodemon": "^1.18.4"
    }

なっていれば大丈夫です。

コマンド:npm run devstartでサーバを起動。これでサーバを再起動しなくって、変更内容はブラウザに反映さります。

データベースの設定 MongoDB

プロジェクトフォルダの直下にmodelsフォルダを作成した後に、

post.jsファイルを作成します。コード内容は以下の通りです。

データベーススーケマの定義をタイトル、作者、内容、作成時期等にします。

const mongoose = require('mongoose');
let Schema = mongoose.Schema;
let postSchema = new Schema({
    title: {
        type: String,
        required: true,
    },
    author: {
        type: String,
        required: true,
    },
    content: {
        type: String
    },
    publish: {
        type: Date
    },
});
// Virtual for post's URL
postSchema.virtual('url').get(() => {
    return '/post/' + this._id;
});
let POST = module.exports = mongoose.model('POST', postSchema);

Applicationファイルの作成

app.jsの中身にコードを追加します。
データベースのインプットと接続関連コードを追加。

//Setup mongoose connection
const mongoose = require('mongoose');
const mongoDB = 'mongodb://127.0.0.1/post'
mongoose.connect(mongoDB);
mongoose.Promise = global.Promise;
const db = mongoose.connection;
db.once('open', () => {
    console.log("Connecting to database " + mongoDB + " ....");
})
db.on('error', (err) => {
    console.error.bind(console, err);
});
//Routesのモジュールのインプット
let indexRouter = require('./routes/index');
let postRouter = require('./routes/posts');
let usersRouter = require('./routes/users');

let app = express();
//タイムの表示フォマット変更用
app.locals.moment = require('moment');
app.use('/', indexRouter);
app.use('/posts', postRouter);
app.use('/users', usersRouter);

routerファイルの作成

routesフォルダにposts.jsファイルを作成します。中身は以下のようにします。
今回GETとPOSTだけを使います。

const express = require('express');
const router = express.Router();
const POST = require('../models/post');
// 
/* GET Postデータリストを取得.Webページに反映 */
router.get('/', function(req, res, next) {
    POST.find({}, (err, posts) => {
        if (err) {
            console.log(err);
        } else {
            res.render('index', {
                title: 'Blog',
                posts: posts
            });
        }
    })
});
/* GET Post追加Webページに反映 */
router.get('/add/', (req, res, next) => {
    res.render('add_post');
});
/* POST Post追加サブミットWebページに反映 */
router.post('/add/', (req, res, next) => {
    let post = new POST();
    post.title = req.body.title;
    post.author = req.body.author;
    post.content = req.body.content;
    post.publish = req.body.publish;

    post.save((err) => {
        if (err) {
            console.log(err);
            return;
        } else {
            res.redirect('/');
        }
    });

});
module.exports = router;

index.jsの中身、HomeページとAboutページレンダリングをここで作成します。

const express = require('express');
const router = express.Router();
// Homeページ
router.get('/', (req, res) => {
    res.redirect('/posts/');
})
// Aboutページ
router.get('/about/', (req, res, next) => {
    res.render('about', { messge: 'About content.' })
});
module.exports = router;

Viewテンプレートの作成

Viewsフォルダに幾つかのpugテンプレートを作成します。

layout.pug [Htmlページのメイン構成を定義]

    doctype html
    html
    head
        meta(charset='utf-8')
        meta(name='viewport' content='width=device-width, initial-scale=1')
        link(href='/css/style.css', rel='stylesheet')
        block title
    body
        .main-header.box-shadows
        .header
            h1 MY BLOG
            p Welcome to the blog of parhat
        ul
            li
            a(href='/') Home
            li
            a(href='/posts/add/') Add New Post
            li
            a(href='/about/') About
        .row
        .leftcolumn
            block content
        .footer.box-shadows
        p(style="opacity:0.5") Copyright © 2018 by parhat

        script(src='/js/jquery.min.js')
        script(src='/js/blog.js')

index.pug [Homeページに表示される内容]

    extends layout
    block title
    title #{title}
    block content
    each post, i in posts
        .card.box-shadows
        h2= post.title
        p(style="opacity:0.5") Author #{post.author}, #{moment(post.publish).format('MM/DD/YYYY')}
        img(src="/img/Desert.jpg" alt="Nature" style="height:380px")
        p= post.content

add_post.pug [postを追加するフォーム]

extends layout
   block content
      h1 #{title}
        .card.box-shadows
           form(method="POST", action="/posts/add")
              .row
                 .col-25
                    label(for='fname') Title
                 .col-75
                    input#fname(type='text', name='title', placeholder='Title..')
             .row
                .col-25
                   label(for='lname') Author
                .col-75
                   input#lname(type='text', name='author', placeholder='Author..')
             .row
               .col-25
                  label(for='subject') Content
               .col-75
                  textarea#subject(name='content', placeholder='Write something..', style='height:200px')
            .row
              .col-25
                 label(for='date') Created
              .col-75
                 input#subject(type="date", name='publish')
           .row
              input(type='submit', value='Submit')

about.pug [Aboutページ]

    extends layout
        block title
            title #{title}
        block content
            .card.box-shadows
                p= messge

publicフォルダにcss,js,imgフォルダがあって、
staticファイルをここから呼ぶ出す可能。今回style.cssファイルを作成します。

結果確認

コマンドプロンプトでサーバ起動します。

コマンド: npm run devstart

f:id:ipx-writer:20181004162659p:plain

http://localhost:3000/posts/

f:id:ipx-writer:20181004162706p:plain

http://localhost:3000/posts/add/

f:id:ipx-writer:20181004162707p:plain

http://localhost:3000/about/

f:id:ipx-writer:20181004162711p:plain

コマンドプロンプトでmongoDBの中身

コマンド: mongo

f:id:ipx-writer:20181004162703p:plain

まとめ

Djangoでもブログを簡単に作ることができましたが、Expressの場合も同じく簡単でした。基本考えが同じで、MVCにしたがっています。

今回は簡単なブログを作って見ましたが、次回はブログにDeleteとユーザログイン機能も追加してみたいと思います。