node-js备忘(二)

一. 模块系统

1.模块作用域:

即使你加载我 你也不能访问我,

除非我想让你访问(exports暴露)

2. exports

exports是一个对象,通过这个对象暴露属性

        exports.add=add
或者
moudle.exports={
    add:add
}
引用模块的脚本可以直接这样用:
var 模块别名 require('模块名')
模块别名.方法

      

如果想直接暴露一个方法直接用 不用 模块名.方法 的话

        moudle.exports=add

      

因为,每一个文件模块都有一个moudle对象,他有一个成员叫exports, 又声明了一个exports对象让他等于moudle.exports

        var exports=moudle.exports

      

所以,我们用exports=add 无法暴露.只能用moudle.exports=add;

3.require

        var 模块别名 require('模块名')

      

require两个作用:1. 执行模块中的代码 2.导出模块中的暴露对象

4.require缓存规则

(1). 优先加载缓存中的模块 //如果已经加载过的模块又被加载,会直接从缓存中加载

(2). 判断模块标识

①核心文件本质也是文件,已经被编译成二进制文件了,可以直接调用

②用户模块 require('路径')

③第三方模块

  • 不可能有第三方包和核心模块同名
  • 调用时,先找当前模块目录下的node_moudles文件夹
  • 再去找该文件夹下的package.json文件
  • 在文件中找main,main属性就记录了当前模块的入口
  • 如果找不到package.json或者main,则node会自动找该目录下的index.js
  • 如果以上操作都不成立,则进入上一级目录的node_moudles文件夹寻找
  • 如果还没有,再进入上一级,直到根目录,然后报错
  • 注意,一个项目只有一个node_moudles,存放于根目录

二.npm相关

1.npm官方网站

npm | build amazing things

我们可以再网站中搜索包

2. npm常用命令

①版本

        npm -v

      

②升级

        npm install --global npm

      

③常用命令

        npm init      //初始化npm 生成package.json文件
npm init  -y   //快速初始化npm ,跳过向导

npm install 包名    //下载包
npm i 包名  //同上
npm install 包名  --save    //下载包,并记录在package.json文件中
npm i 包名 -S   //同上
npm install      //一次性将记录在package.json文件中的包全部下载下来
npm i

npm uninstall 包名   //卸载包
npm un 包名       //同上
npm uninstall  包名 --save  //卸载包,同时撤销在package.json文件中的记录
npm un 包名 -S    //同上

npm --help    //帮助

      

3、npm被墙问题

淘宝 NPM 镜像
        npm install --global cnpm

      

然后把之前的指令中的npm改为cnpm即可

4、描述文件

建议每一个项目要有一个 package.json文件(包描述文件)

我们想弄清楚项目的依赖包情况,可以访问这个package.json文件

这个文件可以用以下命令自动创建:

        npm init

      

这是一个询问式的命令,会询问你一些项目基本信息,按需填写就可以

v2-bcc3366070a1bb57453034134987ee4a_b.jpg

此时已经生成了package.json

v2-3d578665bf3c6d8eedb28de2a43df5f5_b.jpg


然后

        npm install 包名 --save

      

//备注:npm 5.x以后不写save也可以自动保存了

此时json文件会记录下我们安装的包

v2-4e1bc0319f89dd9e1da02f648ab4a89b_b.jpg

v2-dd964299fb3d5a14a8fb14c13d60116c_b.jpg

如果node_moudles被删除了,我们可以直接执行以下命令一口气装好

        npm install    //此命令会重新下载package.json中的dependencies中的包

      

三、express模块初步使用

原生的http表现不足,需要使用框架加快效率,也让代码高度统一
Express - 基于 Node.js 平台的 web 应用开发框架

1、安装方式

        npm install express --save
      

2、hello world

        var express = require('express')
var app = express();//实例化一个服务程序

//当服务器收到请求"/"时的逻辑
app.get('/', (req, res) => {  
    res.send('hhello express!你好!')
})

app.listen(3000,()=>{ //让服务器程序在3000端口监听
    console.log('app is listening at Port 3000');
    
})

      

我们发现了express的几个好处:

①响应不用end了 ②url不用自己解析了 ③中文不用自己转码了

3、基本路由

get:

        app.get('/', (req, res) => {
    res.send('hello express!你好!')
})

      

post

        app.post('/',(req,res)=>{
    res.send(req);
})

      

4、静态服务 //指定公开目录

        app.use('/public/',express.static('./public/'))

      

这样就公开了public中的所有资源,可以访问了

v2-989f6272148a7c3cd930b7b4aa677631_b.jpg

此外,我们可以省略第一个参数,这时url也省略对应的层

        app.use(express.static('./public/'))

      

v2-c8a0c4c4c0bef82cf5fff3433e156c8c_b.jpg

其实,我们可以给文件路径起url别名,例如:app.use('/a/',express.static('./public/')),

上面这种做法其实是起别名的一种特殊情况

5、解析get请求中的数据

        req.query   //会直接返回一个对象

      

例如:我们的get请求如下:

127.0.0.1:3000/commit?

        app.get('/commit',(req,res)=>{
    console.log(req.query);
})

      

v2-27d90b25aa3cf6576b06c32fe4fed4e9_b.jpg

6、在express中配置使用art-template模板引擎

(1).安装art-template

        cnpm i  art-template -S
cnpm i express-art-template -S

      

(2).使用

①、指定后缀名的文件用art-template渲染:

        app.engine('html', require('express-art-template'))

      

当渲染以.html结尾的文件时,使用art-template模板引擎

express-art-template是用来把art-template整合在Express中的

虽然不需要加载art-template但它是express-art-template的依赖,所以必须安装

②、使用respone.render(views目录下文件,渲染参数)来进行渲染

express有一个约定,希望开发人员把页面文件都放在views目录及其子目录下,

同时,express为responce提供了对应的render方法,此方法默认不可用,当配置了模板引擎时,可用!第一个参数不能写路径(但可以写views的子目录),默认会去views路径下查找模板

        var express = require('express')
var app = express();//实例化一个服务程序

app.engine('html', require('express-art-template'))
//当渲染以.html结尾的文件时,使用art-template模板引擎
//express-art-template是用来把art-template整合在Express中的
//虽然不需要加载art-template但它是express-art-template的依赖
//所以必须安装

app.get('/', (req, res) => {
    res.render('index.html', {
        name: 'lili',
        age: 18,
        sex: 'girl'
    })
    //express为responce提供了对应的render方法,此方法默认不可用
    //当配置了模板引擎时,可用. 
    //express有一个约定,希望开发人员把页面文件都放在views目录及其子目录下
    //第一个参数不能写路径(但可以写views的子目录),默认会去views路径下查找模板
})
app.get('/admin', (req, res) => {
    res.render('admin/adminIndex.html', {//render里可以写views的子目录
        admin: '莉莉'
    })
})

app.listen(3000, () => { //让服务器程序在3000端口监听
    console.log('app is listening at Port 3000');
})

      

v2-7d0838c4972646928da82039d7be3c37_b.jpg

v2-1a986ae4f36a6ed43ecaa125640890b0_b.jpg

③、如果想修改目录(一般不需要)则:

        app.set('views','新的路径')

      

7. 重定向

        res.redirect('/')

      

8、解析get请求中的数据

需要借用一个插件 body-parser

(1)安装

        cnpm install body-parser --save

      

(2)引包

        var bodyParser = require('body-parser');

      

(3)配置

配置 body-parser后,会在req对象上增加一个属性叫body

        app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); 

      

(4) 此时,res.body就可以用了

        var express = require('express')
var app = express();//实例化一个服务程序
var bodyParser = require('body-parser');

app.engine('html', require('express-art-template'))
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true }));

var user;//创建一个对象接收用户信息

app.get('/', (req, res) => {
    res.render('index.html', user)
})
app.get('/admin', (req, res) => {
    res.render("admin/adminIndex.html")
})
app.post('/post', (req, res) => {  //post到/post页面
    console.log(req.body)  //req.body可用了
    user = req.body  //把它赋给user
    res.redirect("/") //重定向到首页
})
app.listen(3000, () => {
    console.log('app is listening at Port 3000');
})

      

9.设置状态码

        res.status(500).send("读取文件错误:") //设置了状态码,还返回了错误信息

      

10.操作文件中的数据

express中没有专门的文件读写API,所以还是使用fs.readFile()

此外注意读取时

        app.get('/', (req, res) => {
    fs.readFile('./views/db.json', 'utf8', (err, data) => {
                                    //第二个参数加'utf8'会读出utf8字符串
        if (err) { res.status(500).send("读取文件错误:" + err); };
        res.render("index.html", {
            food: ["apple", 'orange', 'banana'],
            students: JSON.parse(data).students
                      //文件读出的是字符串,所以应该转换成对象,再调用属性
        })
    })
})

      

11.路由模块的提取

(1).引用与暴露

实际工作中我们应该将工程模块化,不应将所有逻辑卸载一个app.js中,这就涉及了文件的引用与参数的暴露问题

我们常用的方法是:

在app.js中 require 一个模块 ,在模块中又要引用app对象,所以我们在模块中封装一个函数并暴露,这个函数有一个形参app

app.js引入后调用时,把自己的app对象传递给这个函数

举例如下:

在app.js中

        var express = require('express')
var router=require('./router')

var app = express()
var port = 3000
app.engine('html', require('express-art-template'))

app.use('/public/', express.static('./public/'))
app.use('/node_modules/', express.static('./node_modules/'))


router(app)//调用router函数,同时把app对象传给他
app.listen(port, () => console.log(`app listening on port` + port))

      

在router.js中

        var fs = require('fs')
module.exports = (app) => {  //封装一个函数并暴露,需要形参app
    app.get('/', (req, res) => {
        fs.readFile('./views/db.json', 'utf8', (err, data) => {
            if (err) { res.status(500).send("读取文件错误:" + err); };
            res.render("index.html", {
                food: ["apple", 'orange', 'banana'],
                students: JSON.parse(data).students
            })
        })
    })
}

      

但是,express提供了更好的方法:

(2) express路由模块

①.引用express,实例化其中的Router路由容器对象

        var express =require('express')
//1.创建一个路由容器
var router=express.Router()

      

②.把请求都挂载在router这个对象中

③.把router这个对象导出

④app.js引入这个模块,同时获得router这个对象

⑤app对象使用use方法使用router这个对象

例子:

router.js

        var fs = require('fs')
var express = require('express')
//1.创建一个路由容器
var router = express.Router()
//2.把请求都挂在router中
router.get('/', (req, res) => {
    fs.readFile('./views/db.json', 'utf8', (err, data) => {
        if (err) { res.status(500).send("读取文件错误:" + err); };
        res.render("index.html", {
            food: ["apple", 'orange', 'banana'],
            students: JSON.parse(data).students
        })
    })
})
//3.把router导出
module.exports = router

      

app.js中

        var express = require('express')
var router=require('./router')  //4.app引用router

var app = express()
var port = 3000
app.engine('html', require('express-art-template'))

app.use('/public/', express.static('./public/'))
app.use('/node_modules/', express.static('./node_modules/'))
app.use(router)  //5. app使用router
app.listen(port, () => console.log(`app listening on port` + port))

      

13.封装异步回调函数

如果获取一个函数中异步操作的结果,则必须通过回调函数来获取

先看一个错误的代码: 由于return不会等待fs.readFile的执行结果,所以obj=undefined

        exports.findAll=function findAll() {
    var obj
    fs.readFile(dbPath, 'utf8', (err, data) => {
        obj=JSON.parse(data).students
    })
    return obj
}  //错!!!!!由于异步,这种函数是无法正确返回返回值的!!!!!!

      

要得到返回值,则应采用回调的方式

        exports.findAll = (callback) => {  
    //如果有人想调用findAll,则必须传入一个回调函数
    fs.readFile(dbPath, 'utf8', (err, data) => {
        //这个回调函数要有err,data两个形参
        if(err){//如果readFile失败了 这个err是readFile的
            callback(err)//则callback会传递err给回调函数
        }else{
            callback(null,JSON.parse(data).students)
            //否则callback会传递data给回调函数 这个data是readFile的
        }
    })
}

      

如果有人想调用findAll

        router.get('/students', (req, res) => {
    students.findAll((err, students) => { //调用findAll,必须传入一个回调函数
        if(err) return res.status.send("读取文件错误"+err) 
         //如果callback传出的err不是null,则报错
        res.render("index.html",{
            food:['apple','orange'],
            students:students  //接收到callback传递的students(data)
        })
    })

      

这种方式与其说是把数据传出来处理,不如说是使用者把逻辑传入了封装好的函数中处理逻辑

关键是转变为:上层定义下层调用的思路 具体应用详见综合练习.

14.JSON处理

(1)将字符串转换为JSON对象

        students = JSON.parse(data)

      

(2)将JSON对象转换为字符串

        str= JSON.stringify(students )

//我们还可以顺便调整字符串内容
str = JSON.stringify({
 students: students
        })

      

15.如何自己编写服务器渲染及数据处理的后端app

  • 处理模板
  • 配置开放静态资源
  • 配置模板引擎
  • 简单路由表设计
  • 路由设计
  • 提取路由模块
  • 由于我们需要操作文件或数据库,所以要封装一个.js专门处理他们
  • 实现具体功能

16.小技巧

(1)如何快速找到一个不错的HTML页面?

建议去bootstrap看看

起步 · Bootstrap v3 中文文档 Examples 全局 CSS 样式 · Bootstrap v3 中文文档

17. express如何处理404页面??

需要使用中间件

        app.use(function(req,res){})

      

18.综合练习

此练习为一个迷你学生信息管理系统

v2-e2bfdd7bbf4c4adcd6b57a0fc843c33f_b.jpg https://github.com/zfdok/node_stu_mgr

运行时先执行 npm install 重装一下依赖库

再用 nodemon app 启动服务

输入 127.0.0.1/3000访问首页

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值