简单学了下nodejs web开发框架express,以及一些相关的技术…
关于express的部分主要参考:Node.js开发框架Express4.x、Node.js + Express 构建网站简单示例
需要注意的是,express 4.x 构建器独立成了一个模块,如果要使用系统中的express命令,就必须安装独立的generator:
npm install -g express express-generator bower supervisor express -e bower-express
supervisor 是个好东西,代码变更可以热加载,自动重启:supervisor app.js
(一).首先来看主文件,app.js:
var express = require(‘express‘), ejs = require(‘ejs‘), routes = require(‘./routes/index‘), users = require(‘./routes/users‘), session = require(‘express-session‘), RDBStore = require(‘express-mysql-session‘); var app = express(); // 定义视图路径及修改ejs模板后缀名 app.set(‘views‘, ‘views‘); app.engine(‘.html‘, ejs.__express); app.set(‘view engine‘, ‘html‘); app.use(require(‘body-parser‘).urlencoded({ extended: false })); // 定义静态文件路径 app.use(express.static(‘public‘)); app.use(express.static(‘bower_components‘)); // session保存 const options = { host : ‘1.1.1.1‘, user : ‘test‘, port : 5029, password : ‘test‘, database : ‘test‘ }; app.use(session({ secret : ‘test‘, store : new RDBStore(options), cookie : { maxAge: 10000 }, resave : true, saveUninitialized : true })); // URL路由 app.get(‘/‘, routes.index).post(‘/‘, routes.index); // 显示404错误及输出 app.use(function(req, res, next) { var err = new Error(‘Not Found‘); err.status = 404; next(err); }); // 生产环境异常打印 if (app.get(‘env‘) === ‘development‘) app.use(function(err, req, res, next) { res.status(err.status || 500); res.render(‘error‘, { message: err.message, error: err }); }); // 启动及端口 //require(‘http‘).createServer(app).listen(3000); app.listen(3000, function() { console.log(‘Express server listening on 3000‘); });
由于没装No-SQL数据库,因此就用mysql来缓存session,
进入express生成的项目后使用npm安装即可:npm install express-mysql-session
用法很简单,启动项目后会在目标库自动新建一张innodb表,可以将其改为memory引擎:
ALTER TABLE sessions MODIFY data VARCHAR(5000),ENGINE=MEMORY;
当然,使用mongos或者rethinkdb会更方便,问题是node模块太多了有点眼花缭乱不知道用哪个好(bug少)……譬如:
npm install express-session-rethinkdb connect-rethinkdb session-rethinkdb
(二).好吧,接下来看“action”,routes/index.js:
var router = require(‘express‘).Router(), mysql = require(‘mysql‘); const options = [{ host : ‘1.1.1.1‘, user : ‘test‘, port : 5029, password : ‘test‘, database : ‘test‘, dateStrings : true }, { { host : ‘1.1.1.2‘, user : ‘test‘, port : 3306, password : ‘test‘, database : ‘test‘, dateStrings : true }, { { host : ‘1.1.1.3‘, user : ‘test‘, port : 3307, password : ‘test‘, database : ‘test‘, dateStrings : true//, multipleStatements : true }]; module.exports.index = function(req, res) { var connection, sql; if (req.method == ‘POST‘ && req.body && req.body.host && /^[1-3]$/.test(req.body.host) && req.body.title && req.body.sql) { //var pool = mysql.createPool(options[2]); connection = mysql.createConnection(options[req.body.host]); sql = req.body.sql; } else { res.render(‘index‘, { ‘params‘ : { title : ‘‘, sql : ‘‘, host : ‘‘}, ‘x‘ : ‘[]‘, ‘y‘ : ‘[]‘ }); return; } connection.query(sql, function(err, rows, fields) { if (err) throw err; var x = [], y = []; for (var i in rows) { //if (rows[i].x instanceof Date) x[i] = require(‘moment‘)(rows[i].x).format(‘YYYY-MM-DD‘); x[i] = rows[i].x; y[i] = rows[i].y; } res.json({ ‘x‘ : x, ‘y‘ : y }); }); connection.end(); };
代码很简单,GET请求直接返回页面(当然也可以处理queryString),POST请求返回JSON数据。
一开始不知道node-mysql有个 dateStrings的参数,所以用 moment.js来转换日期格式,也很方便。
在开发页面前先使用 bower下载好所需的jQuery、Bootstrap、ACE、ECharts等库:
bower install ace echarts bootstrap jquery
(三).最后来上展示页面,views/index.html:
<!DOCTYPE html> <head> <meta charset="utf-8"> <title><%-params.title%></title> <link rel="stylesheet" href="bootstrap/dist/css/bootstrap.min.css"> </head> <body> <div id="editor" style="height:60px;font-size:16px"><%-params.sql%></div> <form style="width:60%;height:90px;padding:10px 40px"> <div class="form-group col-xs-4" style="padding-left:0px"> <select class="form-control" name="host"> <option value="">Select Host</option> <option value="0">1.1.1.1:5029</option> <option value="1">1.1.1.2:3306</option> <option value="2">1.1.1.3:3306</option> </select> </div> <div class="form-group col-xs-4" style="padding-left:0px"> <input type="text" name="title" class="form-control" placeholder="title" value="<%-params.title%>" /> </div> <button type="button" onclick="query()" class="btn btn-primary">Query</button> </form> <hr /> <div id="main" style="height:400px"></div> <script src="echarts/build/dist/echarts.js"></script> <script type="text/javascript" src="jquery/dist/jquery.min.js"></script> <script type="text/javascript" src="bootstrap/dist/js/bootstrap.min.js"></script> <script type="text/javascript" src="javascripts/ace/src-min-noconflict/ace.js"></script> <script type="text/javascript"> // js在下面 ↓↓↓↓↓ </script> </body>
以上的JS代码如下:
$(‘select‘).val(<%-params.host%>); var editor = ace.edit(‘editor‘), myChart, options = { tooltip: { show: true }, legend: { data : [‘<%-params.title%>‘] }, xAxis : [{ type : ‘category‘, data : <%-x%> }], yAxis : [{ type : ‘value‘ }], series : [{ ‘name‘ : ‘<%-params.title%>‘, ‘type‘ : ‘bar‘, ‘data‘ : <%-y%> }] }; editor.setTheme(‘ace/theme/sql‘); editor.getSession().setUseWrapMode(true); editor.getSession().setMode(‘ace/mode/sql‘); // 路径配置 require.config({ paths: { echarts: ‘echarts/build/dist‘ } }); // 使用 require( [ ‘echarts‘, ‘echarts/chart/bar‘ ], function (ec) { myChart = ec.init($(‘#main‘).get(0)); myChart.setOption(options); } ); function query() { myChart.showLoading(); $.ajax({ url : window.location.pathname, cache : false, type : ‘POST‘, dataType : ‘json‘, data : $(‘form‘).serialize() + ‘&sql=‘ + editor.getValue(), success : function(obj) { options.legend.data[0] = $(‘:text‘).val(); options.xAxis[0].data = obj.x; options.series[0].data = obj.y; myChart.clear(); myChart.hideLoading(); myChart.setOption(options); } }); }
注意:
- echarts的 setOption 方法是更新操作,因此要先clear图表后重新绘图;
- ACE是一个源码编辑器,同大名鼎鼎的CodeMirror类似,API也是大同小异;
- 如果bower 下载的ACE没有编译,前往ace-builds页面下载。
至此,一个简单的web应用就诞生了,就像 ChartSQL做的那样,可以再完善ajax异常处理、node-mysql的连接池等。
好久没碰过前端相关的技术,写起来各种生疏,代码拙劣、欢迎指教。最后来一张效果图: