使用Node.js+expressjs从零开始搭建博客系列之一:搭建web基本框架

一、环境介绍:

  • 操作系统:Linux
  • 编程语言:node.js 7.x
  • web框架: express 4.x
  • 模板引擎: handlebars
  • 数据库: MySQL 5.6
  • 前端web框架:bootstrap 3.x

注:为什么要使用node.js 7.x呢?

因为node.js 7.x可以使用async+await以同步的模式进行异步编程。使用node.js启动项目时,需要带—harmony_async_await,即:

  1. node --harmony_async_await app.js

二、知识准备

1. express:

express是一个基于node的web框架,它简单且功能强大,提供了基本的MVC架构,比较适合WEB开发以及API服务。其官网为:http://expressjs.com/,中文网为:http://expressjs.com.cn。

2. handlebars

handlebars是一个前端模板引擎,可以使用于js前端,也同样可以使用于后台node,它高效、简单轻巧,因为轻量,所以自带功能较少,但是可以通过各种helper扩展其功能。官网http://handlebarsjs.com/

3. npm

npm是node.js的包管理工具,用于安装、卸载、升级、删除包,类似于JAVA的maven,PHP的composer,python的pip,ruby的gem,lua的luarocks,openresty的opm。官网为https://www.npmjs.com/,国内淘宝镜像为http://npm.taobao.org/。

三、初始化项目

创建项目目录一种是通过express-generator,一种是手动创建。

(一)、手动创建项目:
1、创建项目目录:
  1. cd /data/program/nodeapp
  2. mkdir nodeblog
  3. cd nodeblog
  4. mkdir -p public/static/images
  5. mkdir -p public/static/js
  6. mkdir -p public/static/css
  7. mkdir routes
  8. mkdir views
  9. mkdir -p tmp/logs
  10. mkdir libs
  11. mkdir models

注:

  • public目录为静态资源目录
  • routes为路由文件目录(也就是控制器目录)
  • tmp为临时文件目录(包括日志文件等)
  • views为视图目录
  • libs为自定义函数或模块目录
  • models为模型目录
2、使用npm初始化项目:
  1. npm init

3、安装express模块:
  1. npm install express --save

注:

  • 使用npm install packageName 是指使用npm这个包管理工具来安装一个叫packageName的模块
  • --save表示写入到package.json这个文件中
  • 发现项目目录下多了一个node_modules的目录,它用于存放本项目的node模块
4、创建入口文件:
  1. //加载express这个模块
  2. const express = require('express');
  3. //实例化express
  4. const app = express();
  5. //创建一个路由
  6. app.get('/', function(req, res){
  7. res.send('hello, world!');
  8. });
  9. //在控制台打印一行文字
  10. console.log('express start on port 3000');
  11. //启动应用,并监听3000端口(即在3000端口开启node服务)
  12. app.listen(3000);

注:

  • const是ES6新添加的关键词,作用和var类似,但也有区别
  • app.get('/')表示当请求类型为GET,请求地址为/时,处理这个请求时有一个匿名函数,包括两个参数:req表示请求对象,res表示响应对应
5、在浏览器中输入本地3000端口

即:

http://localhost:3000

(二)、使用express-generator创建项目(新手建议使用第一种方式)
1、安装express和express-generator
  1. npm install -g express --save
  2. npm install -g express-generator
2、创建项目目录
  1. cd /data/program/nodeapp
  2. /usr/local/node/bin/express nodeblog

注:

  • 目录有一个bin,这个目录是用于存放启动应用的脚本(它将入口文件与启动脚本分开了,启动脚本中调用入口文件)

四、使用handlebars模板引擎

1、安装handlebars
  1. npm install express-handlebars --save
2、在入口文件加入模板引擎的相关配置
  1. //加载path模块(用于处理路径的模块)
  2. const path = require('path');
  3. //加载handlebars模块
  4. const handlebars = require('handlebars');
  5. //设置视图路径
  6. app.set('views', path.join(__dirname, 'views'));
  7. //设置模板引擎为handlebars并设置模板后缀为.html
  8. app.set('view engine', 'html');
  9. app.engine('html', handlebars({extname : '.html'}));

注:

  • __dirname表示是当前的文件目录(和PHP的__DIR__类似)
  • path.join是拼接路径使用的,使用它不用管系统的路径分隔符了
  • handlebars的模板默认后缀为.handlebars,这里使用.html
3、在应用中使用模板

前提先建立一个模板

  1. app.get('/', function(req, res){
  2. res.render('index/index');
  3. });

因为模板路径为views,模板后缀为.html,所以模板的路径为views/index/index.html

4、使用布局模板

在handlebars中使用布局模板使用简单:将第2步的app.engine这一行改成如下:

  1. app.engine('html', handlebars({extname : '.html', defaultLayout:'layout.html'}));
  • 布局模板默认目录为views/layouts,可以通过layoutsDir这相配置项来修改

扩展:handlebars实例化函数(构造函数)的配置选项:

  • extname:模板扩展名
  • layoutsDir:布局模板目录
  • partialsDir:partials文件(碎片文件,也可以认为是组件文件)目录
  • defaultLayout:默认布局文件
  • helpers:注册的各种helper助手函数(这个后面具体讲)
  • compileOptions:编译参数

五、项目结构优化

1、入口文件减压

如果所有的操作都在入口文件中进行,那入口文件将非常的大,也不美观,因此需要将相应的内容都移到单独的文件,如路由分发的都移动到一个叫router.js的文件中。

  1. cd /data/program/nodeapp/nodeblog
  2. cd libs
  3. vim router.js

输入以下内容:

  1. module.exports = function(app){
  2. app.get('/', function(req, res){
  3. res.render('index/index');
  4. });
  5. };

在入口文件中将分发部分替换成:

  1. const router = require('./libs/router.js');
  2. router(app);
2、其他自定义类的扩展
(1)自定义函数:helper.js
  1. const helper = {}
  2. module.exports = helper;
(2)自定义模型:db.js
  1. const db = {};
  2. module.exports = db;
(3)自定义配置:conf.js
  1. module.exports = {};
3、添加静态资源的支持:
  1. app.use(express.static(path.join(__dirname, 'public')));
  • app.use是express调用中间件
  • express.static是为了标识静态资源的目录(后期可以将静态资源交给CDN,或者交给nginx)