Node.js教程之用Node.js搭建程序心得
沉沙 2019-03-11 来源 : 阅读 551 评论 0

摘要:本篇文章探讨了Node.js教程之用Node.js搭建程序心得,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

本篇文章探讨了Node.js教程之用Node.js搭建程序心得,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

Node.js教程之用Node.js搭建程序心得

<


1、express — 基于 Node.js 平台的 web 应用开发框架 
       这次的文程序,就是基于这个框架下面做开发的,一个mvc的架构,不过这个框架的作者在04年的时候已经转投GO了.因为之前做php开发接触过yii和thinkphp,都是mvc的,所以这个还是比较好入门的,也比较好理解,这个框架是node上面最多人使用的。 
     安装很简单,使用npm就可以了
$ npm install -g express-generator
这个是安装express的程序(并不是项目,只有添加了这个程序以后才可以创建express项目)
然后就可以新建工程(项目)
$ express -e blog
$ cd blog && npm install
这样子一个文工程就建立起来了,接下来就只要跑起来就可以了 
可以直接在项目的根目录运行npm start或者进入bin目录直接node www都是可以的,大概看一下目录结构
app.js:启动文件,或者说入口文件 
package.json:存储着工程的信息及模块依赖,当在 dependencies 中添加依赖的模块时,运行npm install,npm 会检查当前目录下的 package.json,并自动安装所有指定的模块 
node_modules:存放 package.json 中安装的模块,当你在 package.json 添加依赖的模块并安装后,存放在这个文件夹下 
public:存放 image、css、js 等文件 
routes:存放路由文件 
views:存放视图文件或者说模版文件 
bin:存放可执行文件 
先来看看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 routes = require(‘./routes/index‘);
var users = require(‘./routes/users‘);
//这个应该叫实例化这个项目吧
var app = express();
// 设置view的目录和使用的模板引擎,这里使用ejs,关于ejs,这个就是在html里面怎么来输出路由里面的变量的东西,和在html里面嵌套php代码很像
app.set(‘views‘, path.join(__dirname, ‘views‘));
app.set(‘view engine‘, ‘ejs‘);
// 项目的ico
//app.use(favicon(__dirname + ‘/public/favicon.ico‘));
//日志记录的中间件
app.use(logger(‘dev‘));
//解析son的中间件
app.use(bodyParser.json());
//解析url encoded请求的中间件
app.use(bodyParser.urlencoded({ extended: false }));
//解析cookie的中间件
app.use(cookieParser());
//这里是express现在唯一的内置中间件,静态文件存放的目录
app.use(express.static(path.join(__dirname, ‘public‘)));
//这就使用路由了,其实我们是可以在app.js里面写好所有的方法,但是这样后面就不好维护,我们应该把方法单独拿出来,放在index.js里面去,这里就只用应用他
app.use(‘/‘, routes);
app.use(‘/users‘, users);
//简单来说就是404页面
app.use(function(req, res, next) {
    var err = new Error(‘Not Found‘);
    err.status = 404;
    next(err);
});
// error handlers
// development error handler
// will print stacktrace
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
        });
    });
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render(‘error‘, {
        message: err.message,
        error: {}
    });
});
module.exports = app;
接下来就可以在index.js里面写各种方法了
2、调试 
     一般我们在修改代码以后,要先停掉之前运行的项目,然后重新开启,这个就和php有不一样,这样会很麻烦,但是我们可以通过一个模块来解决这个问题
$ npm install -g supervisor
安装 supervisor 。使用 supervisor 命令启动 app.js:
$ supervisor app.js
这样就不用每次关掉然后再开启,但是实际上,这样当代码有错的时候还是会一直重启执行,难以看清错误的提示,其实不好用。
3、中间件 
     什么是中间件,其实这个我也想了很久找了很多资料,后面发现简单理解为类似php里面的插件,引入了就可以实现一些功能,不需要你自己再大费周章来实现 
4、页面通知flash
     在php里面,我们可以使用一些alter之类的来提醒用户一些信息,在node这或者说express里面,可以使用flash功能,也是一个中间件,后面代码里面就可以使用来做提示了,例如这样的
这样在下面return的哪个跳转页面就有这个登出成功的提示 
5、crypto
     这个是node上面一个加密算法,因为js自带并没有md5的之类的加密算法,所以就要用到这些,内置了一些md5、sha1、sha256、sha512等算法,使用方法。
首先包含进来
crypto  = require(‘crypto‘);
var md5  = crypto.createHash(‘md5‘);
        password = md5.update(‘需要加密的字符串‘).digest(‘hex‘);
最后的password就是加密以后的字符串了,最后面的digest(‘hex’)的作用是以16进制的格式做输出,因为默认的是2进制的,会出现乱码,其实还有很多其他的加密方式。具体可以参考这篇文章 
https://cnodejs.org/topic/504061d7fef591855112bab5
6、multer上传模块
var express = require(‘express‘)
var multer  = require(‘multer‘)
//这里是定义上传所在文件夹,这个是绝对路径,建议在前面加上dirname这些,要不就回上传到你所在服务器的根目录了
var upload = multer({ dest: ‘uploads/‘ })
var app = express()
//第一种,这个表示你上传的只有一个文件,而且文件名字是avatar
app.post(‘/profile‘, upload.single(‘avatar‘), function (req, res, next) {
  // req.file is the `avatar` file
  // req.body will hold the text fields, if there were any
})
//最多12同样名字为photos的文件夹,假如多了就会报错了
app.post(‘/photos/upload‘, upload.array(‘photos‘, 12), function (req, res, next) {
  // req.files is array of `photos` files
  // req.body will contain the text fields, if there were any
})
//这个就是一次性定义比较多名称的文件了
var cpUpload = upload.fields([{ name: ‘avatar‘, maxCount: 1 }, { name: ‘gallery‘, maxCount: 8 }])
app.post(‘/cool-profile‘, cpUpload, function (req, res, next) {
  // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
  //
  // e.g.
  //  req.files[‘avatar‘][0] -> File
  //  req.files[‘gallery‘] -> Array
  //
  // req.body will contain the text fields, if there were any
})
但是其实上面这些都不是很好,因为都是在上传的时候还需要重新写一次文件的名字,因为上传上去到服务器的文件名称是随机生成的,还没有后缀,所以我就写了一个model来统一实现
var multer  = require(‘multer‘);
var storage = multer.diskStorage({
     //设置上传后文件路径,uploads文件夹会自动创建。
    destination: function (req, file, cb) {
        cb(null, ‘../public/images‘)
     },
    //给上传文件重命名,获取添加后缀名
    filename: function (req, file, cb) {
        var fileFormat = (file.originalname).split(".");
        cb(null, file.fieldname + ‘-‘ + Date.now() + "." + fileFormat[fileFormat.length - 1]);
    }
 });
 var multerUtil = multer({
    storage: storage
 });
 module.exports = multerUtil;
这里就是定义好了上传文件夹和上传以后文件的命名方式,使用方法如下
var muilter = require(‘../models/multerUtil.js‘);
//在这里定义好前端的几个上传文件
var upload = muilter.fields([
    {name : ‘file1‘} ,
    {name : ‘file2‘} ,
    {name : ‘file3‘} ,
    {name : ‘file4‘} ,
    {name : ‘file5‘}
]);
//实际调用
app.post(‘/upload‘,function(req,res,next) {
    upload(req,res,function(err){
        if (err) {
            req.flash(‘error‘,‘上传失败‘);
            return res.redirect(‘/upload‘);
        }
        req.flash(‘success‘,‘文件上传成功‘);
        res.redirect(‘/‘);
    })
});
这样的话,就使用起来比较有模块的思维
7、markdown
 这个东西其实没有太多好多的,其实就是因为我们平时保存的东西可能含有一些html的格式。但是保存到数据库然后输出出来的时候,系统可能无法识别,就要转化一下
var markdown = require(‘markdown‘).markdown;
doc.post = markdown.toHTML(doc.post);
然后在前端做输出的时候需要这样
<%- post %>
这样就可以识别到那些HTML的标签了
8、mongoose
在这个项目里面使用的数据库是mongodb,其实我也是第一次接触mongodb,大概了解了一下,就是一个介于关系型数据库(mysql)和非关系型数据库(redis)之间的一种数据库,支持的数据结构很多,也很松散,有点类似json这样子,而且查询语言很强大,node的很多项目都采用它,书里面使用的是原生的写法,例如下面
  //打开数据库
  mongodb.open(function (err, db) {
    if (err) {
      return callback(err);
    }
    //读取 posts 集合
    db.collection(‘posts‘, function (err, collection) {
      if (err) {
        mongodb.close();
        return callback(err);
      }
      //根据用户名、发表日期及文章名进行查询
      collection.findOne({
        "name": name,
        "time.day": day,
        "title": title
      }, function (err, doc) {
        if (err) {
          mongodb.close();
          return callback(err);
        }
      });
    });
  });
我只是要查询一个数据,又open又close太麻烦了,后面发现有这个mongoose,发现用起来很简单,就是保存的时候,需要整理好一下概念
链接我写了一个db.js
var mongoose = require(‘mongoose‘);
var Schema   = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var url      = ‘mongodb://localhost/blog‘;
mongoose.connect(url);
var db = mongoose.connection;
db.on(‘error‘,console.error.bind(console,‘连接错误:‘));
db.once(‘open‘,function(callback){
  //第一次打开记录,这里可以写一些链接上以后的信息
});
module.exports = {
    db       : db ,
    Schema   : Schema ,
    mongoose : mongoose ,
};
然后使用的时候
var mongodb  = require(‘./db‘);
var Schema   = mongodb.Schema;
var db       = mongodb.db;
//这个类似我们要定义好一个数据库的字段一样,我们也需要对你操作的这个数据库进行一个初始化
var PostSchema = new Schema({
    name         : String ,
    title        : String ,
    post         : String ,
    tags         : [] ,
    comments     : [] ,
    pv           : {type:Number,default:0},
    reprint_info : {
        reprint_to : [{
            name: String,
            head: String
        }],
        reprint_from : {
            name  : String,
            title : String,
            day   : String
        }
    },
    time         : {
        date   : {type:Date , default:Date.now} ,
        year   : String ,
        month  : String ,
        day    : String ,
        minute : String ,
    },
});
//这个就实例化了这个对象了,可以使用这个Model来进行数据库的操作(不包含保存.save())
var PostModel = db.model(‘post‘,PostSchema);
//使用方法,对比上面那一段,这里简直简洁太多了
PostModel.find({}).sort(‘-_id‘).exec(function (err, rs) {
    if (err) {
        return callback(err);
    }
    callback(null,rs);
})
//但是要重点说明一下关于保存数据的方法,首先我们要对上面定义好的Model进行赋值,这里面的数据都是我在项目里面的,实际使用要实际的编写
var postEntity = new PostModel({
    name  : this.name ,
    time  : time ,
    title : this.title ,
    post  : this.post ,
    tags  : this.tags
});
//然后就save就可以了
postEntity.save(function(err , rs) {
    if (err) {
        return callback(err);
    }
    callback(null , rs[0]);
})
这只是一些基础的查询和插入,还有更新和删除distinct,等等一系列方法,还需要好好研究。官方文档 
https://github.com/Automattic/mongoose
整个项目学习下来就是一个感受,node发展很快,做页面很方便,但是暂时还没有感受到异步的优势,毕竟这个项目只是一个入门的项目,了解到一些基本的操作,还有一个感受就是英文真的很重要,因为这个node在国内发展的时间还不是十分久,所以文档资料都是英文的,看起来还是很痛苦。
       
            $(function () {
                $(‘pre.prettyprint code‘).each(function () {
                    var lines = $(this).text().split(‘\n‘).length;
                    var $numbering = $(‘<ul/>‘).addClass(‘pre-numbering‘).hide();
                    $(this).addClass(‘has-numbering‘).parent().append($numbering);
                    for (i = 1; i <= lines; i++) {
                        $numbering.append($(‘<li/>‘).text(i));
                    };
                    $numbering.fadeIn(1700);
                });
            });
            

本文由职坐标整理发布,学习更多的相关知识,请关注职坐标IT知识库!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程