149.Node.js学习笔记(三)2018.12.03

2 篇文章 0 订阅
1 篇文章 0 订阅

1. 知识点

  • 模块系统
    • 核心模块
    • 第三方模块
    • 自己写的模块
    • 加载规则以及加载机制
    • 循环加载
  • npm
  • package.json
  • Express
    • 第三方web开发框架
    • 高度封装了http模块
    • 更加专注于业务,而非底层细节
    • 知其所以然
  • 增删改查
    • 使用文件来保存数据(锻炼异步编码)
  • MongoDB
    • (所有方法都封装好了)

2. 反馈

  • 书籍:
    • 《JavaScript 高级编程》第三版
    • 《JavaScript 语言精粹》
  • each 与 forEach 比较
    • art-template 和 jQuery 无任何关系
    • each 是 art-template 的模板语法,专属的
    • {{each 数组}}
    • <li{{ $value }}/li>
    • {{/each}} 这是 art-template 模板引擎支持的语法,只能
      模板字符串中使用
    • $.each(数组, function)
    • $(‘div’).each(function) 一般用于遍历 jQuery 选择器选择到的伪数组实例对象
    • forEach 是 EcmaScript 5 中的一个数组遍历函数,是 JavaScript 原生支持的遍历方法 可以遍历任何可以被遍历的成员
    • jQuery 的 each 方法和 forEach 几乎一致
    • 由于 forEach 是 EcmaScript 5 中的,所以低版本浏览器不支持

3. 复习

  • 网站开发模型
    • 黑盒子
    • 写代码让它变得更智能
    • 按照设计好的讨论供用户使用
  • 在Node中使用 art-template 模板引擎
    • 安装
    • 加载
    • templae.render()
  • 客户端渲染和服务器渲染的区别
    • 最少两次请求,发起ajax在客户端使用模板引擎渲染
    • 客户端拿到的就是服务端已经渲染好的
  • 处理留言本案例首页数据列表渲染展示
  • 处理留言本案例发表留言功能
    • 路径
    • 设计好的请求路径
  • 掌握如何解析请求路径中的查询字符串
    • url.parse()
  • 如何在 Node 中实现服务器重定向
    • header(‘Location’,’/’)
    • 301 永久重定向,浏览器会记住;搜索引擎会抓取新的内容而保留旧的网址。
    • 302 临时重定向,浏览器不记忆;搜索引擎在抓取新内容的同时,也将旧的网址替换为重定向之后的网址。
      Node 中的 console (REPL) 使用

4. PHP和Node比较

  • PHP+Apache(默认帮你封装好了很多底层细节操作)
  • 在Node中,比较偏底层,很多东西需要亲自写代码来实现。
  • 在Node中,我们开启的Web服务是一个完整的黑盒子,它不像php。
  • php中无论是代码还是网页,都可以直接通过web url路径来访问。
  • 在Node中开启的服务器,默认是和盒子,所有资源都不允许用户来访问,用户可以访问哪些资源由具体的开发人员编写设计的代码为准。

5. Node中的模块系统

  • 使用Node编写应用程序主要就是在使用:
    • ECMAScript语言
      • 和浏览器不一样,在Node中没有 BOM、DOM
    • 核心模块
      • 文件操作的fs
      • http服务的http
      • url路径操作模块
      • path路径处理模块
      • os操作系统信息
    • 第三方模块
      • art-template
      • 必须通过npm下载才可以 使用
    • 咱们自己写的模块
      • 自己创建的文件

6. 什么是模块化

  • 文件作用域
  • 通信规则
    • 加载 require
    • 导出 export

7. CommonJS模块化规范

在Node中的JavaScript还有一个很重要的概念:模块系统。

  • 模块作用域
  • 使用require方法用来加载模块
  • 使用exports接口对象用来导出模块成员

7.1 加载 require

  • 语法:
    • var 自定义变量 = require(‘模块’)
  • 两个作用:
    • 执行被加载模块中的代码
    • 得到被加载模块中的exports导出接口对
  • 导出exports
    • Node中是 模块 haul作用域,默认文件中所有成员只在当前文件模块中有效
    • 对于希望可以被其他模块访问的成员,我们就需要把这些公开的成员都挂载到exports接口对象中就可以了
  • 导出多个成员(必须在对象中):
exports.a =  123
exports.b = 'hello'
exports.c =  function(){
    console.log('ccc');
}
exports.d = {
    foo: 'bar'
}
  • 导出单个成员(字符串、函数):
module.exports = 'hello'

以下情况会覆盖:

module.exports = 'hello'
module.exports = function(x,y){
    return x+y
}

也可以这样导出多个成员:

module.exports = {
    add: function(){
        return x+y
    },
    str: 'hello'
}
  • 原理解析
    export 是 module.exports的一个引用:
// var module = {
//    export = {}
// }
// var exports = module.exports

console.log(exports === module.exports) // => true

exports.foo = 'bar'
// 等价于
module.exports.foo = 'bar'

// return module.exports

7.2 exports 和 module.exports 的区别

  • 每个模块中都有一个module 对象
  • module对象中有一个exports对象
  • 我们可以把需要导出的成员都挂载到module.exports接口对象中
    • 也就是:module.exports.xxx=xxx的方式
    • 但是每次都module.exports.xxx=xxx很麻烦,调用太多了
    • 所以node为了方便,同时在每一个模块中都提供了一个成员叫:exports
    • exportx ===module.exports结果为true
    • 所以对于:module.exports.xxx=xxx的方式完全可以:exports.xxx=xxx
  • 当一个模块需要导出单个成员时候,这个时候必须使用:module.exports=xxx的方式
  • 不要使用exports = xxx,导出单个成员这种方式不管用
    • 因为每个模块最终向外return的是module.exports
    • 而exports只是module.exports的一个引用
    • 所以即便你为exports = xx重新赋值,也不会影响module.exports
  • 但是有一种赋值方式比较特殊:exports = module.exports这个用来重新建立引用关系
  • 之所以让大家明白这个道理,是希望可以更灵活的去用它
  • Node是一个比肩Java,php的一个平台
  • JavaScript既能写前端也能写服务端

8. require方法加载规则

深入浅出Node.js(三),深入Node.js的模块机制

如果想要了解更多底层细节,可以自行参考:《深入浅出Node.js》中的额模块系统章节

www.infoq.com/cn

  • 核心模块
    • 模块名
  • 第三方模块
    • 模块名
  • 用户自己写的
    • 路径
  • 优先从缓存加载

main.js

require('./a')

// 优先从缓存加载
// 由于在a中已经加载过b了
// 所以这里不会重复加载
// 可以拿到其中的接口对象,但是不会重复执行加载的代码
// 这样做的目的是为了避免重复加载,提高加载效率
var fn = require('./b')
console.log(fn)

a.js

console.log('a.js被加载了')
var fn = require('./b')

console.log(fn)

b.js

console.log('b.js被加载了')
module.exports = function(){
	console.log('hello b.js')
}

输出结果:

a.js被加载了
b.js被加载了
[Function]
[Function]

  • 判断require模块标识
    • 核心模块:
      • 核心模块的本质也是文件
      • 核心模块文件已经被编译到了二进制文件中了,我们只需要按照名字来加载就可以了
        • require(‘fs’)
        • require(‘http’)
    • 第三方模块:
      • 凡是第三方模块都必须通过npm来下载

      • 使用的时候就可以通过require(‘包名’)的方式来进行加载才可以使用

      • 不可能有任何一个第三方包和核心模块的名字是一样的

      • 既不是核心模块,也不是路径形式的模块

      • 先找到当前文件所处目录中的 node_modules目录

        • node_modules/art-template
        • node_modules/art-template/package.json 文件
        • node_modules/art-template/package.json 文件中的 main 属性
        • main 属性中就记录了 art-template 的入口模块
        • 然后加载使用这个第三方包
        • 实际上最终加载的还是文件
        • 如果 package.json 文件不存在或者 main 指定的入口模块是也没有
        • 则 node 会自动找该目录下的 index.js
        • 也就是说 index.js 会作为一个默认备选项
        • 如果以上所有任何一个条件都不成立,则会进入上一级目录中的 node_modules 目录查找
        • 如果上一级还没有,则继续往上上一级查找。。。
        • 如果直到当前磁盘根目录还找不到,最后报错:
        • can not find module xxx
      • var template = require(‘art-template’)

      • 注意:我们一个项目有且只有一个 node_modules,放在项目根目录中,这样的话项目中所有的子目录中的代码都可以加载到第三方包

      • 不会出现有多个 node_modules

      • 模块查找机制

        • 优先从缓存加载
        • 核心模块
        • 路径形式的文件模块,自己定义的模块
        • 第三方模块
          • node_modules/art-template/
          • node_modules/art-template/package.json
          • node_modules/art-template/package.json main
          • index.js 备选项
          • 进入上一级目录找 node_modules
          • 按照这个规则依次往上找,直到磁盘根目录还找不到,最后报错:Can not find moudle xxx
        • 一个项目有且仅有一个 node_modules 而且是存放到项目的根目录
        • 例如:我需要查找 art-template模块,这个模块已经被我安装到了项目中的node_modules中,
          • 先去node_modules中找到 art-template文件夹
          • 其次,在 art-template文件中找到packge.json
          • 然后,在packge.json文件中找到main.js属性
          • 通过main.js属性值找到找到具体的.js文件指向
          • 最后,执行指向的.js文件
    • 自己写的模块

9. npm

  • node package manager

  • npm 是JavaScript 世界的包管理工具,并且是 Node.js 平台的默认包管理工具。

  • 通过 npm 可以安装、共享、分发代码,管理项目依赖关系。

  • npm网站

  • npm命令行工具

    • npm的第二层含义就是一个命令行工具,只要你安装了node就已经安装了npm
    • 常用命令:
    • 1.npm –version 查看版本

    • 2.npm install –global npm 版本升级

    • 3.npm init
      npm init -y可以跳过向导,快速生成

    • 4.npm install
      一次性把dependencies选项中的依赖项全部安装
      简写:install i

    • 5.npm intall 包名
      只下载包

    • 6.npm install –save 包名
      下载并保存依赖项(package.json文件中的dependencies选项)
      简写:npm i -S 包名

    • 7.npm uninstall 包名
      只删除,如果有依赖性依然会保存
      简写:npm un 包名

    • 8.npm uninstall 包名 --save
      删除的同时也会把依赖信息也去除
      简写:npm un -S 包名

    • 9.npm help
      查看使用帮助

    • 10.npm 命令 --help
      查看指定命令的使用帮助
      例如:npm uninstall --help来查看使用帮助

  • 解决npm 被墙问题

    • npm存储包文件的服务器在国外,有时候会被墙,速度很慢,所以我们需要解决这个问题。
    • http://npm.taobao.org
    • 安装淘宝的cnpm:
    • #在任意目录执行都可以
      #–global表示安装到全局,而非当前目录
      #–global不能省略,否则不管用
      npm install –global cnpm

    • 接下来安装包的时候把之前的npm替换成cnpm即可
      • 例如:
    • 这里还是走国外的npm服务器,速度比较慢
      npm install jquery
      使用cnpm就会通过淘宝的服务器来下载jquery
      cnpm install jquery

    • 如果不想安装cnpm又想使用淘宝的服务器来下载:
    • npm install jquery –registry https://registry.npm.taobao.org

    • 但是每次手动添加参数很麻烦,我们可以把这个选项加入配置文件中:
    • npm config set registry https://registry.npm.taobao.org
      查看 npm 配置信息: npm config list
      只要经过上面命令的配置,以后所有的npm install都会默认通过淘宝的服务 器来下载。

10. package.json

  • 我们建议每个项目都要有一个package.json文件(包括描述文件、就像产品说明书一样),用来记录安装的包日志

  • packjson文件是通过 npm init命令的方式自动初始化出来的

  • 这里是引用

  • npm生成的packjson文件

  • 在这里插入图片描述

  • 如果node_modules删除了也不用担心,只需要:npm install就会自动把package.json中的dependencies中所有的依赖项都下载下来。

  • 建议执行npm install包名的时候都加上–save这个选项,目的是用来保存项目依赖信息

  • 例如:npm加载jquery、art-template包

  • 在这里插入图片描述

10.1 package.json和package-lock.json

  • npm5以前是不会有package-lock.json这个文件的
  • npm5以后才加入了这个文件
  • 当你安装包的时候,npm都会生成或者更新package-lock.json这个文件
    • npm5以后的版本安装包不需要加–save参数,它会自动保存依赖信息
    • 当你安装包的时候,会自动创建或者更新package-lock.json这个文件
    • package-lock.json这个文件会保存node_modules中所有包的信息(版本、下载地址)
      • 这样的话,重新npm install的时候速度就可以提升
    • 从文件来看,有一个lock称之为锁
      • 这个lock是用来锁定版本的
      • 如果项目依赖了1.1.1版本
      • 如果你重新install,其实会下载最新版本,而不是1.1.1
      • 我们的目的就是希望可以锁住1.1.1这个版本
      • 所以这个package-lock.json这个文件的另一个作用:就是锁定版本号,防止自动升级新版本

11. Express

  • 原生的http在某些方面表现不足以应对我们的开发需求,所以我们就需要使用框架加快我们开发效率,框架的目的就是提高效率,让我们的代码更高度统一。
  • 在Node中,有很多web开发框架,以express为主
  • 官网: http://expressjs.com/
  • 案 例:
// 0 安装
npm init 
npm install express --save
// 1 引包
var express = require('express');

// 2 创建服务器应用程序,也就是原来的http.createServer
var app = express();

// 3 公开指定目录
// 只要这么做了以后,就可以直接通过/public/xx的方式访问public目录中的所有资源了
// 例如:
app.use('/public/',express.static('./public/'));
app.use('/node_modules/',express.static('./node_modules/'));

// 当服务器接收到get请求 / 的时候,执行回调处理函数
app.get('/',function(req,res){
    res.send('hello express!')
}); 

// 当服务器接收到get请求 /about 的时候,执行回调处理函数
app.get('/about',function(req,res){
    res.send('你好,我是express!')
}); 

// 注意:当访问不存在的文件路径时,express会自动返回404

// 相当于 server.listen
app.listen(3000,function(){
    console.log('app is running at port 3000');
});
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值