kindle本「JavaScriptでのWeb開発Node.js Express + MongoDB + ReactでWebアプリを開発しよう〜 その1 〜」のまとめ。
点数
63点
感想
あまり良い内容ではなかった。
雑な説明が多く、特にPassportの説明は不明な点が多かった。
MongoDbに触れることができた点はよかった。
Expressのインストール
npm init
npm install express --save-dev
※entry pointはapp.jsとするtouch app.js
node app.js
で実行
"use strict";
const http = require('http');
const express = require('express');
const app = express()
app.use((req, res, next) => {
res.send('hello');
});
var server = http.createServer(app);
server.listen('3000');
pug
pugとは
Railsでお馴染みのHamlに似たテンプレートエンジン。
かつてはjadeという名前だった。
ejsやectと比べて圧倒的に記述量を減らすことができる。
pugのインストール
npm install pug --save-dev
app.jsへの追記
const path = require('path');
// 〜省略〜
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.get('/', (req, res, next) => {
res.render('index', {title: 'Hello World'});
});
views/index.pugの作成
doctype html
html(lang="ja")
head
meta(charset="utf-8")
body
h1 #{title}
MongoDB
MongoDBとは
- NoSQLと呼ばれる新しいタイプのデータベースで、RDBMSのように事前に構造を定義する必要がない。
(ただし、通常は型や最大値・最小値を定義する) - BSONと呼ばれる独自のデータ形式で保持する。
- BSONはJSONのバイナリ版のようなもの(実運用上はほぼ同じ)であり、JavaScriptオブジェクトをそのまま保存することができる。
- MySQLなどに比べて大量のアクセスに耐えられる。
MongoDBのインストール
- Macの場合
brew tap mongodb/brew
の後にbrew install mongodb-community
※brew install mongodb
ではインストールできなくなったhttps://qiita.com/kazuki5555/items/b80f1f313137dffbb351
https://github.com/mongodb/homebrew-brew
Linuxの場合
yumにmongoDB用の設定を追加してからsudo yum install mongodb-org
https://qiita.com/daikiojm/items/a3953a56d6328e59a4e7 - データ格納用ディレクトリを作成
mkdir db
- 実行
mongod --dbpath db
※コマンドはmondo
がクライアント、mongod
がサーバ
mongoコマンドの使い方
mongo
use データベース名
でデータベースの作成・切り替え
例)use chatapp
db.コレクション名.insert({xxx: yyy})
で挿入
例)db.messages.insert({username: "山田 太郎", message: "Hello"})
※コレクションが存在しない場合は作成されるdb.コレクション名.find()
で取得
MongoDBには最低1つのデータベースを定義し、その中に最低1つのコレクションを格納する。
例)chatappデータベースにusers, messagesコレクションを作成する。
mongoose
mongooseとは
node.js上でmongoDBを扱うためのライブラリ。
コレクション毎にスキーマを定義しなければならない。
mongooseの使い方
- インストール
npm install mongoose --save-dev
- app.jsに接続処理を追記
const mongoose = require('mongoose');
// 〜省略〜
mongoose.connect(
'mongodb://localhost:27017/chatapp',
{ useNewUrlParser: true, useUnifiedTopology: true },
err => {
if (err){
console.error(err);
} else{
console.log("successfully connected to MongoDB.");
}
}
);
mkdir schema & touch chema/Message.js
でスキーマファイルを生成
const mongoose = require('mongoose');
const Message = mongoose.Schema({
username: String,
message: String,
date: {type: Date, default: new Date()} // dateに現在日時が登録される
});
module.exports = mongoose.model('Message', Message)
- app.jsに登録処理を追記
const Message = require('./schema/Message');
// 〜省略〜
const newMessage = new Message({
username: req.body.username,
message: req.body.message
});
newMessage.save((err)=>{
if (err) {
throw err;
}
console.log("successfully inserted to MongoDB.");
});
登録フォームをpugで作成
- views/update.pugを作成
doctype html
html(lang="ja")
head
meta(charset="utf-8")
body
h1 メッセージを保存
form(action="update" method="POST")
input(type="text" name="username" placeholder="名前")
textarea(placeholder="メッセージ" name="message")
button(type="submit") 送信
- app.js (body-parserはexpressと一緒にインストールされるので、個別のインストールは不要)
const bodyParser = require('body-parser'); // POSTをreq.bodyに格納する
// 〜省略〜
app.use(bodyParser.urlencoded({ extended: false }))
app.get('/update', (req, res, next) => {
res.render('update');
});
app.post('/update', (req, res, next) => {
const newMessage = new Message({
username: req.body.username,
message: req.body.message
});
newMessage.save((err) => {
if (err) {
throw err;
}
res.redirect('/');
});
});
データ表示画面をpugで作成
- views/index.pugを作成
doctype html
html(lang="ja")
head
meta(charset="utf-8")
body
h1 投稿一覧
section
each msg in messages
div
h2 #{msg.username}
time #{msg.date}
p #{msg.message}
- app.js
Message.find({}, (err, msgs) => {
if (err) {
throw err;
}
res.render('index', {messages: msgs});
});
express-fileupload
type="file"
のinput要素で送信されたデータはbody-parserではパースできないため、express-fileuploadを使う。
npm install express-fileupload --save-dev
- app.js
const fileUpload = require('express-fileupload');
// 〜省略〜
app.use(fileUpload());
app.post("/update", (req, res, next) => {
if(req.files && req.files.image) {
req.files.image.mv(`./images/${req.files.image.name}`, err => {
if (err) {
throw err;
}
});
}
});
- update.pug
form(action="update" method="POST" encType="multipart/form-data")
input(type="text" name="username" placeholder="名前")
textarea(placeholder="メッセージ" name="message")
input(type="file" name="image")
button(type="submit") 送信
アップロードした画像を表示する
app.use(express.static(ディレクトリ名));
でディレクトリを公開することできる。
- app.js
app.use("/images", express.static(path.join(__dirname, 'images')));
// またはapp.use(express.static('./'));
// 〜省略〜
const newMessage = new Message({
username: req.body.username,
message: req.body.message,
image_path: `/images/${req.files.image.name}`
});
- schema/Message.jsにパス保存用のimage_pathを追加
const Message = mongoose.Schema({
username: String,
message: String,
date: {type: Date, default: new Date()},
image_path: String
});
- index.pug
doctype html
html(lang="ja")
head
meta(charset="utf-8")
body
h1 投稿一覧
section
each msg in messages
div
h2 #{msg.username}
time #{msg.date}
p #{msg.message}
if msg.image_path
img(src=msg.image_path)
Passport
Express用の認証ミドルウェア。
ローカル認証やOAuth認証用のモジュールをインストールして使う。
Passportはセッションを使ってユーザー認証を行っている。
Passportのインストール
npm install passport passport-local express-session --save-dev
app.js
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const session = require('express-session');
// 〜省略〜
app.use(session({ secret: 'HogeFuga', resave: false, saveUninitialized: false, }));
app.use(passport.initialize());
app.use(passport.session());
// 〜省略〜
app.post('/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login'
}));
// セッション用のシリアライズ(これがないと動作しない)
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
// ログインしていない場合の処理
passport.use(new LocalStrategy({
usernameField: 'username',
passwordField: 'password'
}, function (username, password, done) {
process.nextTick(function () {
if (username === "test" && password === "test") {
return done(null, username)
} else {
console.log("login error")
return done(null, false, { message: 'パスワードが正しくありません。' })
}
})
}));
new LocalStrategy()
はpassport.authenticate('local')
でセッションが存在しない場合に処理が実行される。- 引数のusername, passwordにはルーティング/loginのPOSTパラメータが自動的にセットされる。
- doneの第1引数にエラーの有無、第2引数にセッションに保存するデータ、をセットする