Node填坑教程——整理文件
如果你能把所有代码写进一个文件,并且能很好的管理、协调、多人开发。那么可以跳过这期(请务必带我飞)。
我们接着完善上期的代码,给代码分家。
node并没有启动入口,更没有固定的项目结构,文件配置。这些全部要靠自己动手,靠约定,正所谓约定由于配置。因为作者书读的少,只会MVC结构,姑且按照MVC结构来分。
建立如下目录。
- /bin/ : 项目的启动文件,也可以放其他乱七八糟的脚本。如果你有多种环境或者多个入口,这样分就很有必要的
- /configure/ : 配置文件,上图中根据生产环境和开发环境配置了两个文件夹,分别是development和production
- /lib/ : js源代码,app.js文件也在这里
- /logs/ : 日志文件
- /node_modules/ : 通过npm包管理中间件都在这,包括session,模板,日志等中间件,你自己安装的中间件也在这
- /public/ : 暴露的文件夹,从名字就可以看出,图面前端js脚本和css会在这里
- /src/ : 其他语言的文件,如果是coffeescript的项目,编译前的文件会放在这里,编译后的文件在lib里,这里我们暂时用不到
- /test/ : 单元测试
- /views/ : 模板文件
- /app.js : 约定俗成的项目入口
- /package.json : 配置你项目依赖的包,使用npm命令 npm install -d 会自动安装里面记录的中间件,非常方便。由于nodejs的中间件不完全是脚本组成的,也会包含C写的编译文件,各环境下不尽相同,所以通过npm,本地下载编译是非常重要的
下面我们来填充文件
lib/app.js
1 var express = require('express'); 2 var app = express(); 3 4 module.exports = app;
bin/start.js
1 var app = require('../lib/app'); 2 3 var port = 3000; 4 var server = app.listen(port, function () { 5 console.log('http server listening on port %s', server.address().port); 6 });
这里bin/start.js充当程序的启动文件。通过node bin/start.js启动项目。现在访问http://127.0.0.1:3000/能看到Cannot GET /的字样就说明成功了。
我们来写第一个路由
controllers/homeController.js
1 var action = { 2 get: function (req, res, next) { 3 return res.send('ok'); 4 } 5 6 }; 7 8 module.exports = action;
routes/homeRoute.js
1 var express = require('express');
2 var controller = require('../controllers/homeController');
3 var router = express.Router();
4
5 router.get('/', controller.get);
6
7 module.exports = router;
routes/index.js
1 var homeRoute = require('./homeRoute'); 2 module.exports = function (app) { 3 app.use(homeRoute); 4 }
routes/app.js
1 var path = require('path'); 2 var express = require('express'); 3 var route = require('./routes'); 4 var bodyParser = require('body-parser'); 5 var app = express(); 6 7 app.use(bodyParser.json()); 8 app.use(bodyParser.urlencoded({ extended: true })); 9 10 route(app); 11 12 13 module.exports = app;
现在第一个路由已经配置好了,访问 http://127.0.0.1:3000/ 就能看到ok的提示。
接下来我们添加一个能交互的页面。
首先我们需要一个模板引擎,使用npm安装
E:\project\heron-lesson\demo3>npm install ejs --save
修改app.js文件
1 var path = require('path'); 2 var express = require('express'); 3 var route = require('./routes'); 4 var bodyParser = require('body-parser'); 5 var app = express(); 6 app.use(bodyParser.json()); 7 app.use(bodyParser.urlencoded({extended: true})); 8 app.set('views', path.join(__dirname, '../views')); 9 app.set('view engine', 'ejs'); 10 app.engine('ejs', require('ejs').renderFile); 11 route(app); // 路由文件分开 12 13 14 module.exports = app;
由于我们还没讲到数据库,那么先缓存几个数据吧
controllers/listController.js
1 var data = [ 2 {name: '张三', age: 20}, 3 {name: '李四', age: 22} 4 ];
继续填充路由
1 var action = { 2 index: { 3 get: function (req, res, next) { 4 return res.render('list/index', {data: data}); 5 } 6 } 7 }; 8 9 module.exports = action;
routes/listRoute.js
1 var express = require('express'); 2 var controller = require('../controllers/listController'); 3 var router = express.Router(); 4 5 router.get('/index', controller.index.get); 6 7 module.exports = router;
routes/index.js,我们这里用了个小技巧给list路由加上了目录/list
1 var homeRoute = require('./homeRoute'); 2 var listRoute = require('./listRoute'); 3 module.exports = function (app) { 4 app.use(homeRoute); 5 app.use('/list', listRoute); 6 }
views/list/index.ejs
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>List</title> 6 </head> 7 <body> 11 <ul> 12 <% data.forEach(function (item) { %> 13 <li>姓名:<%= item.name %>,年龄:<%= item.age %></li> 14 15 <% }) %> 16 </ul> 17 18 </body> 19 </html>
现在访问http://127.0.0.1:3000/list/index ,就能看到两行数据了。注意,如果你输出的中文有问题,请更改你的代码文件,保存为utf-8。
姓名:张三,年龄:20
姓名:李四,年龄:22
我们再添加一个搜索功能
修改页面 /views/list/index.ejs
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>List</title> 6 </head> 7 <body> 8 <form action="" method="post"> 9 搜索:<input type="text" name="q"/> <input type="submit"/> 10 </form> 11 <ul> 12 <% data.forEach(function (item) { %> 13 <li>姓名:<%= item.name %>,年龄:<%= item.age %></li> 14 15 <% }) %> 16 </ul> 17 18 </body> 19 </html>
同上controllers、routes都得改
controllers/listController.js
1 var data = [ 2 {name: '张三', age: 20}, 3 {name: '李四', age: 22} 4 ]; 5 6 var action = { 7 index: { 8 get: function (req, res, next) { 9 return res.render('list/index', {data: data}); 10 }, 11 post: function (req, res, next) { 12 var list = []; 13 data.forEach(function (item) { 14 if (item.name === req.body.q) 15 list.push(item); 16 }); 17 return res.render('list/index', {data: list}); 18 } 19 } 20 }; 21 22 module.exports = action;
routes/listRoute.js
1 var express = require('express'); 2 var controller = require('../controllers/listController'); 3 var router = express.Router(); 4 5 router.get('/index', controller.index.get) 6 .post('/index', controller.index.post); 7 8 module.exports = router;
刷新页面。
就可以根据name字段来完全搜素了。
彩蛋:
每次都要修改routes里的多个文件来路由,是不是太麻烦了呢。
D:\project\heron-lesson\demo3>npm install heron-mvc
安装heron-mvc。github: https://github.com/iheron/heron-mvc
修改lib/app.js
1 var path = require('path'); 2 var express = require('express'); 3 var route = require('./routes'); 4 var bodyParser = require('body-parser'); 5 var app = express(); 6 var mvc = require('heron-mvc'); 7 8 app.use(bodyParser.json()); 9 app.use(bodyParser.urlencoded({extended: true})); 10 app.set('views', path.join(__dirname, '../views')); 11 app.set('view engine', 'ejs'); 12 app.engine('ejs', require('ejs').renderFile); 13 14 mvc.route.load({ 15 routeDir: path.join(__dirname, './routes'), 16 controllerDir: path.join(__dirname, './controllers') 17 }, function (data) { 18 app.use("/" + data.route, data.router); // 优先加载路由 19 }, function (data) { 20 app[data.method]("/" + data.controller + "/" + data.action, data.func); // 没有路由直接加载控制器 会根据控制器的前缀和action名称 生成两级目录 21 }); 22 23 24 module.exports = app;
现在是见证奇迹的时候了。不用再改routes 来处理路由了,甚至可以删除这个了。
该插件会根据controller的前缀和action的名称来自动生成两级目录。如果你要手动控制路由,也会优先加载路由配置。
该项目下载地址:demo3
下载后需通过npm install -d 来安装依赖
下一期如果内容过多会考虑录成视频。大家如果有什么想看的可以给我留言。