node-day3

(1)反馈

  1、本节知识

    node-day3_第1张图片

  2、SEO

    网站运营专业,负责SEO搜索引擎优化,职位SEO运营专员

  3、软件开发版本---设计软件工程学

    node-day3_第2张图片

  4、each与forEach  

    node-day3_第3张图片

    node-day3_第4张图片

  5、node重要性

    

  6、模块加载规则

    node-day3_第5张图片

  7、node网站开发模型

     node-day3_第6张图片

  8、重定向

    node-day3_第7张图片

 

     永久重定向案例:

访问新浪时,会永久重定向

    

    

 

     node-day3_第8张图片

 

 

(2)模块系统

  前言:

    node-day3_第9张图片

   1、什么是模块化?

如果一套平台具有以下特点,那么就是模块化

    node-day3_第10张图片

  2、模块作用域

     node-day3_第11张图片

 

  3、多次添加

     node-day3_第12张图片

 

     

  4、局部导出模块

需求升级:现在希望直接导出的exports对象中的方法和属性,无需再加点执行符去解析

  方式:module.exports

    node-day3_第13张图片

如果模块只需要导出某个成员,而非挂载的方式,可以使用module.exports = 导出成员

    

 

(3)CommonJS模块规范&&加载导出规范

  1、前言

    node-day3_第14张图片

  2、require导入

     node-day3_第15张图片

  3、exports导出

    node-day3_第16张图片

      node-day3_第17张图片

      node-day3_第18张图片

  4、覆盖性

(单个导出语法注意)使用module.exports导出模块时,如果重复导出则会覆盖之前的导出模块

  node-day3_第19张图片

   

   结果为函数,覆盖了之前的字符串

   node-day3_第20张图片

 

(4)exports和module.exports区别

  1、分析

我们可以从底层实现去理解:在node里每个模块内部都有一个自己的对象module,而该module对象里,有一个子对象exports

    node-day3_第21张图片

在node里,谁require该文件,谁就得到module.exports接口对象

    node-day3_第22张图片

     node-day3_第23张图片

我们发现,每次导出接口成员时通过module.exports.xxx = xxx的方式很麻烦,都得通过点.方式
因此node为了简化操作,专门提供了一个变量:exports = module.exports

    也就是说在模块底层实现里,还有这么一句代码

var exports = module.exports

    测试如下

    

     

  2、原理解析

exports是module.exports的一个引用

    node-day3_第24张图片

  3、导出单个模块

当导出单个模块时,需要module.exports即可

    node-day3_第25张图片

  4、思考进阶(面向对象--引用类型)

    为什么导出单个对象不可以使用exports = xxx;直接赋值定义导出???

    

     node-day3_第26张图片

     原理图:引用数据类型

    node-day3_第27张图片

接下来再看个思考题

    node-day3_第28张图片

     结果为hello,为什么呢?

当给obj1重新赋值后,它便指向了新对象,开辟了新的内存空间,如下所示,此时两者已经没有关系

    node-day3_第29张图片

综上分析不能使用exports = xxx来直接导出单个成员

    node-day3_第30张图片

var exports = module.exports
类似于
var obj1 = obj
这里exports只是module.exports的一个引用,所以这里直接给exports直接赋值,并不会影响module.exports,只是指向了新对象而已。
始终要记住:底层实现里最后返回的是module.exports对象

    node-day3_第31张图片

  5、重新赋值,解除引用

此外,这里要注意:一旦给exports重新赋值,便会失去和module.exports的关联,指向新对象,且后期无法使用。
如下所示

    node-day3_第32张图片

    

     node-day3_第33张图片

  6、思考2

对上述代码再次修改如下

    node-day3_第34张图片

     结果如下

    

   7、思考3

再使用module.exports添加如下

    node-day3_第35张图片

     

  8、思考4

接下来再做下调整

    node-day3_第36张图片

     原理如下:

    node-day3_第37张图片

     换为exports与module.exports

      node-day3_第38张图片重定义node-day3_第39张图片

这里注意:此时两者已经没有引用关系,最终return的是module.exports所以只需要看module.exports即可

   9、思考5

接着修改代码

    node-day3_第40张图片

    

   10、思考6

    node-day3_第41张图片

     node-day3_第42张图片

    node-day3_第43张图片

  11、小结

1、exports为modules.exports的一个引用
2、最后node底层模块导出的是module.exports
3、底层代码
    var module = {
        exports:{...}
    } 
4、exports.name等价于module.exports.name,但node为了方便书写,使用module.exports导出单个成员,本质为将该子对象重新赋值  
5、所以只要给exports赋值,便丢失了module.exports的引用关系,后期便不可用

  node-day3_第44张图片

 

 

(5)复习

  node-day3_第45张图片

  1、each和forEach

    node-day3_第46张图片

  2、伪数组对象转数组

Array.prototype.slice.call(jQuery实例对象)

  slice截取拷贝测试:

       node-day3_第47张图片

  底层实现:

       node-day3_第48张图片

  接下来写个伪数组对象

    node-day3_第49张图片

    接下来,伪数组对象转数组,如下所示

    

此时,内部this指向fakeArr伪数组对象

  3、模块导出成员(单个与多个)

  4、301与302的区别

301为永久重定向,浏览器会保留缓存,下次访问url时会直接从缓存里访问跳转(使用较少)
302为临时重定向

  5、exports与module.exports

    node-day3_第50张图片

 

 

 

(6)require加载规则---优先从缓存加载

  1、首先新建测试文件a.js、b.js、c.js

    node-day3_第51张图片

 

 

     执行顺序为

a.js→b.js→c.js→b.js→a.js

c.js执行完毕后返回b.js执行,因为b.js后续没有代码了,所以返回a.js
接着a.js里又调用了c.js,这里注意不会重复调用,而是为了提高性能,优先从缓存加载

验证如下

    

 

 

     分析:

如果之前已经加载过该模块,则直接从缓存里拿取结果,不会重复执行加载
可以拿到接口对象的代码,但不会重复执行里面的代码。
目的:避免重复加载,提高模块加载效率

    node-day3_第52张图片

 

 

 

 

 (7)require标识符分析---即require方法加载规则

  1、模块标识符/模块标识

    也叫

  2、判断模块标识符

    node-day3_第53张图片

  3、路径形式模块标识

     node-day3_第54张图片

   4、非路径形式模块

    node-day3_第55张图片

   5、核心模块位置

    可以在GitHub查看node源码

    node-day3_第56张图片

    node-day3_第57张图片

const用于定义常量,定义后不可再次更改
var用于定义变量

     但安装完成后便被编译到node程序二进制文件中,所以无法直接查看

      node-day3_第58张图片

  6、第三方模块

    ①下载使用

      node-day3_第59张图片

    ②区分第三方模块与核心模块

不可能有任何一个第三方包和核心模块名字重复

    ③读取第三方模块步骤

      node-day3_第60张图片

       node-day3_第61张图片

       node-day3_第62张图片

  7、读取第三方模块步骤--jquery举例

    node-day3_第63张图片

这里jQuery.js和jquery.min.js并不是源码,源码是src目录下文件,这里也是应用了模块化思想,但和node模块化不太一样

    node-day3_第64张图片

   8、验证第三方包如下

    在第三方包art-template入口模块index.js做下修改,如果运行时输出标识,则代表猜想正确

    node-day3_第65张图片

     node-day3_第66张图片

   9、手动编写模拟第三方包读取加载步骤

    ①node_modules下创建文件目录a

    ②a目录下新建package.json说明文件,里面写入main选项标明入口文件(node相关规定)

    ③入口文件编写代码进行验证

    node-day3_第67张图片

     加载导入第三方模块---a

    

     验证如下:

    node-day3_第68张图片

   10、其他情况---默认备选项index.js

node默认规则:如果第三方模块不存在package.json或者main选项指定为空,则node会自动寻找目录下的index.js

    node-day3_第69张图片

 

   11、模块查找机制---完整模块加载规则---链式查询加载

    node-day3_第70张图片

    所以下面情况可以正常查找到

    node-day3_第71张图片

   12、小结

    

 

     

(8)require模块加载查找机制

  node-day3_第72张图片

   注意:这里不会进行兄弟查找,和原型链类似,只会进行嵌套查询

  node-day3_第73张图片

因此blog项目下,在b目录中main.js查找第三方模块,无法查找到a目录下的node_modules目录中的模块
不会在兄弟间查找

  

 

 

(9)npm

node package manager包管理工具

node-day3_第74张图片

npm一般有两层含义:npm网站、命令行工具

 

 

   1、npm网站

npm网站服务器里的包名不可能重复,通过npm下载的必须存在于该服务器
也可以通过该网站发包

    node-day3_第75张图片

 

 

   2、npm命令行工具

    node-day3_第76张图片

  3、npm常用命令

    安装+初始化

    node-day3_第77张图片

 

 

     卸载依赖注意事项:

    node-day3_第78张图片

 

 

     查看帮助

    node-day3_第79张图片

 

 

   4、cnpm

    

 

  5、解决npm被墙问题

    node-day3_第80张图片

    node-day3_第81张图片

 

  6、测试如下

cnpm init -y
跳过向导步骤,采用默认项,一步到位

    node-day3_第82张图片

 

 

   7、线上淘宝镜像使用规范

如果不想安装cnpm,且仍旧想使用淘宝镜像下载模块,如下所示
  npm i 包名 --registry-https://registry.npm.taobao.org   

     但是上面这种下载方式过于繁琐,每次还需加上后面的链接,所以可以将这个选项加入配置文件里

    node-day3_第83张图片

 

 

     验证:

    

 

 

     node-day3_第84张图片

配置项加入淘宝镜像后,再次通过npm下载包时,便会使用配置项链接下载,提高下载效率

    node-day3_第85张图片

 

 

   8、小结

关于淘宝镜像cnpm用法有两种
    1、可以直接下载cnpm到本地,后期使用时只需将指令里的npm换位cnpm即可
    2、如果不想下载包,也可以将淘宝镜像链接加入配置项镜像注册,此后再次通过npm下载模块时,便会自动使用淘宝镜像链接下载,提高效率

 

 

 (10)包说明文件package.json

场景如下:项目目录下,误删了node_modules依赖目录,此时便无从获取项目依赖模块

 node-day3_第86张图片

 即便node_modules目录还在,也很难知道依赖了哪些模块,因为里面的文件太多

主要因为:下载安装第三方包时--按照依赖下载

node-day3_第87张图片

 

   1、手动创建package.json进行测试

手动创建package.json文件,在里面写个{}空对象,然后在同级目录下开始下载模块
与之前不同的是npm i bootstrap && npm i bootstrap --save,这里多了--save参数,下载后会发现除了多出来node_modules目录,在package文件下也会多出下载依赖项

    node-day3_第88张图片

 

     下载后

    node-day3_第89张图片

dependencies描述当前依赖项

    此时node_modules目录下,除了使用的模块,还有其依赖文件

    node-day3_第90张图片

由此可以看出,文件太多,无法快速查看项目依赖模块,所以这里就体现出了package.json项目说明文件作用

  2、不加--save

下载第三方模块时如果不加--save则不会保存信息到package.json项目说明文件里

  node-day3_第91张图片

  3、小结

在实际开发里,一般package.json说明文件都是通过指令创建,进入向导界面
如下所示

node-day3_第92张图片

package-name 说明文件名
version 版本号,一般从0.0.1低版本开始即可
description 描述
entry point 入口文件,默认index.js,也可以自定义项目目录下的其他js文件
test command 测试命令
git repository 如果项目放置到git,可以将仓库地址填到这里
keywords 关键字,如果要编写发布第三方包到npm网站,以供他人使用,可以写入关键词
author 作者
license 开源许可证

  接下来创建完毕后即可生成package.json文件

  node-day3_第93张图片

注意:此时没有dependencies依赖项,在安装第三方包后才会自动生成

  node-day3_第94张图片

  4、测试

此时如果再次误删了node_modules依赖模块目录,也没有关系,因为这里的packsge.json中保存了依赖项信息,再次执行npm i指令即可

     node-day3_第95张图片

     node-day3_第96张图片

     node-day3_第97张图片

 

(11)Express框架介绍+安装

  1、简介

express翻译为“特快”、“表达”,简单理解就是封装原生http模块后的一个框架

    node-day3_第98张图片

 

 

  2、安装

进入Express官网,首页有Getting started入门导航和Guide指南

    查看Getting started入门导航,里面有安装导向

    node-day3_第99张图片

  3、目录如下

    node-day3_第100张图片

 

 

(12)Express框架基本感知

  1、安装完毕后,开启第一个案例,感受Express框架

首页→指南→hello world案例

    node-day3_第101张图片

  2、这里开始手写案例

    ①项目根目录下新建入口文件index.js,引包

     node-day3_第102张图片

 

 

    ②接下来分析第三方包解析读取步骤

1、读取第三方包说明文件package.json,查找main选项,获取该包的入口文件
2、如果没有或指定错误,则查找备选项express/index.js

    node-day3_第103张图片

  3、 在使用express框架创建服务之前,先来回顾下服务构建模块http创建服务

    ①版本1

var http = require('http')
var server = http.createServer();
server.on('request',function(req,res){
    console.log(req.url)
    res.end('hello world')
})
server.listen(3000,function(){
    console.log('server start running... ...')
})

    ②版本2---简写版

var http = require('http')
var server = http.createServer(function(req,res){
    console.log(req.url)
    res.end('hello world')
}).listen(3000,function(){
    console.log('server start running... ...')
})

  4、接下来使用express框架构建服务

/* 引入第三方包 */
var express = require('express')
/*创建server服务器,也就是原来的http.createServer*/
var app = express()
/*添加响应,类似之前的server.on('request',callback),但这注意是服务器收到get请求/的时候,执行的回调处理函数*/
app.get('/',function(req,res){
    res.send('hello world')
})
/*启动服务器,监听端口*/
app.listen(3000,function(){
    console.log('app is running at port 3000')
})

    同理,当请求/about时,返回“关于我们”

    node-day3_第104张图片

 

     写好后重启服务器,再次测试即可

    node-day3_第105张图片

 

     验证发现,这里没有乱码,不用再处理请求头信息,设置响应内容编码类型

Express根据语言响应特定编码内容,有时也会将请求头Content-Type添加进来,验证如下所示

     node-day3_第106张图片

     node-day3_第107张图片

  5、优势

相对于之前的路径处理(if...else if...else),这里简化了很多,支持并行编写,代码更加简洁

    node-day3_第108张图片

 

   6、内置处理404

express框架内置处理了其他情况,如果路径不存在,则返回对应内容

    node-day3_第109张图片

 

   7、处理开放资源---express.static内置中间件功能

例如public目录下的静态资源,默认不可访问
如果原生处理,则需要做一大堆判断和读取,这里Express框架只需要一个API即可搞定

    node-day3_第110张图片

 

     node-day3_第111张图片

 

     接下来使用Express框架API开放该资源目录

/*公开指定目录,即开放资源目录*/
app.use('/public/',express.static('./public'))

    此后便可以通过localhost:3000/public/js/main.js来访问该静态资源文件,完整如下

/*公开指定目录,即开放资源目录,此后便可以通过/public/xxx访问public下所有开放资源*/
/*
    为express.static函数提供服务的文件创建虚拟路径前缀(该路径在文件系统中实际上不存在),请为静态目录指定安装路径
    现在可以从/ static路径前缀加载公共目录中的文件
    注意:名字随意,最好和开放目录名相同
*/
app.use('/static',express.static('./public/'))/*express.static内置中间件功能*/

    node-day3_第112张图片

这里我的虚拟路径前缀为/static,所以可以通过localhost:3000/static/js/main.js来访问

    node-day3_第113张图片

 

     图片也可以,测试如下

    node-day3_第114张图片

 

   8、多资源开放,即同时开放多个目录

 

     同理,如果想和Apache服务器一样,根据url直接读取文件,也可以将node_modules开放

    node-day3_第115张图片

 

     node-day3_第116张图片

 

   9、小结

开放静态资源、模板引擎等应用,在Express框架里都是一个API的事,这样便提高了开发效率,更多去关注业务逻辑

 

 

(13)本节总结

   node-day3_第117张图片

 

 

 

 

 

 

.

你可能感兴趣的:(node-day3)