最近心血來潮又把 express 玩了一下,寫篇文章來紀錄一下整個過程,會用到的工具如下:
首先安裝 express-generator,這是一個可以自動產生 express 需要內容的工具
$ sudo npm i -g express-generator
安裝好之後,我們切換到我們想要的目錄來產生專案資料夾,我選用 twig 當作我的樣板引擎,我在 PHP 使用 CI 的時候也是選用同一個引擎,可以無痛轉移
/var/www $ sudo express -v twig project
/var/www $ cd project
/var/www/project $ sudo npm i
/var/www/project $ sudo npm i orm mysql --save
專案目錄產生後,我們可以使用 nodemon 來監控目錄,也可以達到修改檔案後自動重起的效果
/var/www/project $ sudo nodemon bin/www
這時候打開 http://10.10.10.16:3000
(我的 vm 測試 IP)就可以看到預設網址,如果希望改 port 的話可以在 env 設定 port,或者直接去改 bin/www
這個檔案
打開 app.js
這是預設的內容
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'twig');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
所有的動作都在這隻 app.js 設定,我們來建立一個 product routes 檔案
routes/product.js
const express = require('express');
const router = express.Router();
router.get('/', function(req, res, next) {
res.render('product/index');
});
module.exports = router;
view/product/index.twig
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h3>This is product page</h3>
</body>
</html>
將 app.js
加上這個 routes 的設定
app.js
var index = require('./routes/index');
var users = require('./routes/users');
var product = require('./routes/product');
var index = require('./routes/index');
var users = require('./routes/users');
var product = require('./routes/product');
app.use('/', index);
app.use('/users', users);
app.use('/product', product);
這時網址改成 http://10.10.10.16:3000/product
,就會看到 This is product page 這幾個字
接下來我們進行資料庫的串連,在 MySQL 內建立一個叫 express
的資料庫,另外建立一個 products
的 table 並且塞入資料
CREATE TABLE `products` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(50) NOT NULL
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
接下來我們來設定資料庫連接,因為我不喜歡全部的東西都塞在 app.js
,所以我另外開一個資料夾來放設置檔
config/db.js
module.exports = (app, orm) => {
app.use(orm.express("mysql://root:123456@127.0.0.1/express", {
define: function(db, models, next) {
models.product = db.define('products', {
id: Number,
name: String
});
next();
}
}));
};
修改 app.js 啟動這個設定,只要放在 app
以及 orm
初始化後即可
app.js
require('./config/db.js')(app, orm);
我們先將 routes/product.js
修改成以下內容,變可以從網址先看到結果
const express = require('express');
const router = express.Router();
router.get('/', function(req, res, next) {
req.models.product.all((err, data) => {
res.json(data);
})
});
module.exports = router;
http://10.10.10.16:3000/product
[{"id":1,"name":"product a"},{"id":2,"name":"product b"}]
這是最基本的用法,但我覺得這樣可重複利用性太低了,所以我們來建立類似 model 機制吧
routes/product.js
const express = require('express');
const router = express.Router();
const Product = require('../model/product.js');
router.get('/', async(req, res, next) => {
try {
const product = new Product(req.models.product);
res.json(await product.getAllNews());
} catch (e) {
res.send(e);
}
});
module.exports = router;
model/product.js
class Product {
constructor(model) {
this.model = model
}
async getAllNews() {
return new Promise((resolve, reject) => {
this.model.all((err, data) => {
if (err) {
reject(err);
}
resolve(data);
})
})
}
}
module.exports = Product;
這樣的執行結果會一模一樣,但把東西拆乾淨模組化了,再修改一次在 view 呈現吧
routes/product.js
const express = require('express');
const router = express.Router();
const Product = require('../model/product.js');
router.get('/', async(req, res, next) => {
try {
const product = new Product(req.models.product);
res.render('product/index', {
products: await product.getAllNews()
});
} catch (e) {
res.send(e);
}
});
module.exports = router;
views/product/index.twig
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h3>This is product page</h3>
{% for product in products %}
<div>product: {{ product.name }}</div>
{% endfor %}
</body>
</html>
以上就是這兩天試玩 express
的整理,沒有實現所謂的 controller 部份,就先把 routes 當 controller,當然一定會有更多更好的方法,再慢慢探索,在此也感謝陳默司大大的指導
沒有留言:
張貼留言