Node.js 学习笔记(3)

Node.js模拟phpStudy

var http = require('http');
var server = http.createServer();
var fs = require('fs')
var path = require('path')
var mime = require('mime')

server.on('request', function(req, res){

    res.setHeader('Content-Type', mime.getType(req.url));
    fs.readFile(path.join(__dirname, "public", req.url), function(err, data){
        res.end(data);
    })
})

server.listen(8888, function(){
    console.log('http://localhost:8888')
})

Request对象的属性

req.urlreq.headersreq.rawHeadersreq.methodreq.httpVersion

请求参数获取

get请求参数获取

var url = require('url')
var urlObj = url.parse(req.url, true);

// urlObj.pathname
// urlObj.query

post请求参数的获取

var querystring = require('querystring')

var bufferList = [];

req.on("data", function(chunk){
    bufferList.push(chunk);
})

req.on("end", function(){
    var result = Buffer.concat(bufferList);

    //获取post参数
    result = result.toString();

    var params = querystring.parse(result);
})

NPM

  1. 初始化一个package.json文件npm initnpm init -y

  2. 下载包npm install 包npm install 包@版本号npm install 包@版本号 包@版本号 包

npm i 包

npm installnpm install --production

  1. 卸载包npm uninstall 包名

  2. 保存依赖信息dependenciesnpm i 包名npm i 包名 --savenpm i 包名 -S

devDependenciesnpm i 包名 --save-devnpm i 包名 -D

package.json

nameversion 1.1.1

scripts: shell命令 npm run 别名

NRM

nrm lsnrm use 服务器名称nrm current nrm test nrm test 服务器名称

nrm add 别名 地址

Hacker-News

 

 

数组的ES5中新增的方法复习

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];


// 1. 遍历 forEach
// arr.forEach(function (v, i) {
//     console.log(v + "====>" + i);
// })

// 2. 映射 map
// 想要获取一个新数组,新数组中的元素是 arr中元素的2倍
// [2, 4, 6, 8, 10, 12, 14, 16, 18]

// var newArr = [];
// arr.forEach(function (v, i) {
//     newArr.push(v * 2);
// })
// console.log(newArr);

// var newArr = arr.map(function (v, i) { 
//     return v * 2;
// })
// console.log(newArr);

// 3. 判断数组中是否有任意元素满足指定条件
// 判断数组里有没有偶数
// var flag = arr.some(function (v, i) {
//     return v % 2 == 0;
// })

// console.log(flag);

// 4. 判断数组中是否所有元素都满足条件
// 判断数组是否全是奇数
// var flag = arr.every(function (v, i) { 
//     return v % 2 != 0;
// })
// console.log(flag);

// 5. 在数组中查找第一个满足条件的元素

// var firstEven = arr.find(function (v, i) {
//     return v % 2 == 0;
// })

// console.log(firstEven);

// 6. 在数组中找所有满足条件的元素
// var newArr = arr.filter(function (v, i) {
//     return v % 2 != 0;
// })

// console.log(newArr)

前端渲染和后端渲染的区别

渲染工作究竟是由谁负责:

  1. 如果是在浏览器端进行渲染工作,则称为前端渲染

    1. 首先向服务器请求页面

      1. 将页面的基本结构渲染出来

        1. 通过ajax请求向后台请求数据

          1. 利用模板引擎将获取到数据渲染到页面中

  1. 如果是在服务器端进行的渲染工作,则称为后端渲染

    1. 首先向服务器请求页面

      1. 服务器会先去根目录读取页面文件

        1. 将数据读取到

          1. 将数据渲染到读取到的页面中

          2. 将渲染好数据的页面返回给浏览器

          3. 浏览器拿到的就是已经渲染好数据的页面!

 

在node.js中使用模板引擎

// art-template 
// 既支持浏览器端使用也支持服务器端(node.js)中使用

// 浏览器端的用法
// 1. 引包
// 2. 准备模板(script type=text/template)
// 3. 渲染(template)  template(模板的id, 要渲染的数据对象)


// node.js中的用法
// 1. 引包
var template = require('art-template');
var path = require('path')

// 2. 准备模板 (1. 以文件作为模板, 2.以字符串变量作为模板)

// 3. 渲染
var obj = {
    msg: "Hello World"
}

// // template(模板文件的路径, 要渲染的数据对象)
// var result = template(path.join(__dirname, 'tpl.html'), obj)

// console.log(result);


// 如果以字符串变量作为模板
// 使用方法如下:

var str = "
{{msg}}
" //1. 根据模板字符串创建一个渲染函数 // template.compile(模板字符串) var render = template.compile(str); //2. 使用渲染函数进行模板渲染 // render(要渲染的数据) var result = render(obj); console.log(result);

art-template以字符串变量作为模板




    
    
    
    Document


    
    
    
    

node.js中的模块化

模块化

概念

将代码按照一定的规则,拆分成一个个小单元(模块)的过程,称之为模块化!

模块化标准

  1. AMD: 异步模块定义 Async Module Definetion require.js

  2. CMD: 通用模块定义 Common Module Definetion sea.js

  3. CommonJS: node.js模块化标准

标准的意义在于,让模块更加通用!!

学习模块化学什么??

  1. 如何定义模块

  2. 如何引用模块

模块化的意义

  1. 便于代码维护

  2. 便于代码复用

node.js的模块化

定义模块

一个js文件就是一个模块

每个模块有自己单独的作用域!

引用模块

require函数就可以用来引用模块

// js文件在引入的时候,.js后缀可以省略
require(模块文件的路径)

模块导出项的设置和接收

  1. 设置模块导出项

module.exports.属性名 = 要导出的内容

module.exports = 要导出的内容

获取模块的导出项模块的导出项会被作为require函数的返回值! 直接接收即可

var 导出项 = require("模块路径")

module.exporst和exports都可以用来导出内容但是,exports只能给对象中添加属性来导出内容

exports.名字 = 导出项

exports不能直接赋值,复制之后没意义

exports = 导出项;  //这种方式不可以!!!

require函数的导入规则说明

require函数

require函数的作用就是用来导入模块的!!

node.js中的模块分类

  1. 核心模块(内置模块) fs path url http querystring

  2. 第三方包模块 mime art-template moment

  3. 目录模块

  4. 文件模块

在引入核心模块和第三方包模块的时候,直接给require函数传递包名称即可:

当require函数接收到一个包名称的时候

  1. 会先去找核心模块中是否有对应的模块,如果找到了就直接使用

  2. 如果没有找到,就去node_modules中查找对应的模块,如果找到了就直接使用

  3. 如果没有找到,就去上一级目录中的node_modules中找,如果找到了就直接使用

  4. 如果没找到继续往上级目录中的node_modules,找到根目录如果还没找到就报错了 can not find module xxx

在引入模块的时候,如果传递给require函数的是一个路径作为参数,那么引入的就是目录模块或者文件模块 ./ ../

  1. 按照路径查找对应的文件, 如果找到了直接引入

  2. 如果没有找到,找文件名对应的 .js .json .node

  3. 如果没有找到,就找路径对应的文件夹

    1. 如果找到了对应的文件夹

1. 判断当前文件夹中是否有package.json文件
    1. 如果没有,就直接引用index.js
    2. 如果有package.json文件,则找main属性
        1. 如果main属性不存在 则引用index.js json node
        2. 如果main属性存在 则引用main属性指定的文件
  1. 如果没找到,就直接报错了

package.json中的main属性

告诉require函数在引入当前包的时候,具体引用哪个文件!

{
    "main": "文件路径"
}

用最基本的方式实现hacker-news

使用文件保存数据

  1. 需要一个data.json文件

  2. 读取数据可以直接利用fs.readFile来读取,读取到之后,需要进行转换,转成数组。(注意,有可能读到的数据为空字符串,或者根本读不到数据, JSON.parse(data || "[]"))

  3. 写入数据,先读取原有数据,再将新数据添加到原有数据中,在写入

查找id对应的元素: 直接使用数组的find的方法

模板引擎在node.js中的使用

以文件作为模板

var template = require('art-template');

var result = template(文件路径, 要渲染的数据对象)

以字符串变量作为模板

var template = require('art-template');
var tpl = "模板字符串"

var render = template.compile(tpl);
var result = render(要渲染的数据对象)

首页和详情页的基本逻辑

  1. 读取数据

  2. 读取模板文件

  3. 调用art-template进行数据渲染

hacker-news优化

  1. 封装了数据操作的方法 readNews getNewsById addNews (都需要使用回调函数)

  2. 封装render函数 (读取模板文件, 将数据进行渲染,返回渲染结果)

模块化

模块化概念

将代码按照一定的规则进行拆分,分成一个个的模块,这个过程就是模块化!

模块化的意义

  1. 便于代码维护

  2. 便于代码复用

模块化的标准

  1. AMD: 异步模块定义 require.js 依赖前置

  2. CMD: 通用模块定义 sea.js 依赖延迟 as lazy as possible

  3. CommonJS: Node.js自己的模块化标准

node.js模块化的具体做法

定义模块

一个js文件就是一个模块,每个模块都有自己独立的作用域!

引用模块

使用require函数就可以引用模块

require('模块名称')
require('./模块路径')

模块导出项的设置

如果模块中要提供内容给外界使用,则需要导出 设置导出项

// modules.exports默认是一个空对象

//1. 利用module.eports来设置
//1.1 给默认的空对象中新增成员
module.exports.成员名 = 要导出的内容
//1.2 直接替换掉默认的空对象
module.exports = 要导出的内容

//2. 利用exports来设置
// 给默认的空对象中新增成员
exports.成员名 = 要导出的内容

// 不能用exports来替换默认的空对象,因为最终导出的module.exports(具体参照上课的图---引用类型数据的特征)

require函数的返回值就是引入的模块的导出项! module.exports是什么,接收到的就是什么

require函数的加载规则

模块分类

  1. 核心模块(内置模块)

  2. 第三方包模块

  3. 目录模块

  4. 文件模块

require函数直接传值模块名称

require('模块名');
// 1. 先去核心模块中查找,如果找到,就用
// 2. 如果没找到,就去当前文件夹中的node_modules中找,如果找到,就用
// 3. 如果没找到,就向上一级目录node_modules中找,,如果找到,就用
// 4. 如果没有,就继续向上找,直到根目录位置,如果根目录还没找到就报错

require函数传递路径作为参数

  1. 先找路径对应的文件,如果能找到,直接用

  2. 如果找不到,就依次找 .js .json .node 如果能找到,直接用

  3. 如果找不到,就去找路径对应的文件夹

    1. 如果文件夹存在,

1. 检查文件夹中是否有pacakge.json
    1. 如果有就看有没有main属性
        1. 如果有,就引入main属性指定的文件
        2. 如果没有,就引入index.js .json .node
            1. 如果index.js ...找不到就报错了
    2. 如果没有main属性 就引入index.js .json .node 如果index.js ...找不到就报错了
2. 如果没有pacakge.json 就引入index.js .json .node 如果index.js ...找不到就报错了
  1. 如果找不到,就报错了

hacker-news模块化改造

  1. 主模块: 负责启动一个http服务器

  2. 路由模块: 负责制定路由规则

  3. 路由处理模块: 负责路由规则中详细的处理逻辑

  4. 数据操作模块: 负责操作数据

  5. 功能扩展模块: 负责给req.res增加功能

 

你可能感兴趣的:(Node.js 学习笔记(3))