Node.js学习心得

我的 Node.js 笔记

    本博客是我自学 Node.js 的学习心得,本来我是想学习 Vue.js,但是学习的过程中发现学习 Vue.js 最好有 Node.js 的基础,所以我转过头来学习 Node.js。学习之前,我对 Node.js 一无所知,即使是现在,我也仅仅是入门而已,但是我对 node.js 的强大已经有了感知。

1. Node.js 基本感知

1.1 Node.js 是什么

  1. Node.js 不是一门语言,也不是库,也不是框架。
  2. Node.js 是 js 的运行时环境
  3. Node.js 可以解析执行 js 代码,这个之前只有浏览器可以做到
  4. 现在的 js 完全可以脱离浏览器运行,因为有了 Node.js。

1.2 Node.js 中的 JavaScript

  • 服务端,完全不操作 DOM 和 BOM
  • 在 Node.js 这个环境中,为 JavaScript 提供了一些服务器级别的 API。例如:
    • 文件的读写
    • 网络服务的构建
    • 网络通信
    • http 等处理

1.3 Node.js 的特性

  • event-driven 事件驱动
  • non-blocking I/O model 非阻塞IO模型(异步)。
  • lightweight and efficient 轻量和高效。

1.4 Node.js 能做什么?

  • Web 服务器后台
  • 命令行工具
    • a. npm
    • b. git
  • 游戏服务器、接口服务器

1.5 学会 Node.js 能做什么?

  • B/S 编程模型
  • Brower-Sever
  • node 只是作为学习 BS 编程的工具

1.6 Node.js 的模块化编程

  • 通过 var 变量名 = require(‘包名’) 来加载文件

1.7 Node.js 的异步编程

  • 回调函数

1.8 Node.js 中修改完代码服务器自动重启

使用第三方命令行工具 :nodemon 来解决频繁的修改代码重启服务器问题。
nodemon 是基于 node.js 开发的命令行工具,所有需要 --global 的在哪执行都行,全局安装

  • 全局安装 :npm install --global nodemon
  • 使用 :之前是 node app.js
    以后是 nodemon app.js
  • 只要是通过 nodemon 启动的服务,它会监视文件变化,当文件发生变化是,它自动重启服务器。

1.9 解决 npm 的被墙问题

1.9.1 可以直接下载 cnpm
1. npm install --global cnpm 
  • 以后再安包,把原来的 npm 替换成 cnpm
1.9.2. 如果不想安装 cnpm 又想用淘宝镜像下载

npm install 包名 --registry =https://registry.npm.taobao.org \

但是这样每次手动这样加参数很麻烦,所以我们可以把这个选项加到配置文件中

npm config set registry https://registry.npm.taobao.org

只要经过这个配置,以后所有的 npm install 都会通过淘宝的服务器下载

1.10 npm 常用命令

  • npm init
  • npm init -y
    • 可以跳过向导,快速生成
  • npm install
    • 一次性把 dependencies 选项中的依赖项全部安装

2. Node.js 的模块系统

2.1 服务端渲染与客户端渲染的区别

  • 如果检查源代码,可以看到页面的数据,那一定是服务端渲染
  • 客户端渲染不利于 SEO 搜索引擎优化
  • 服务端渲染可以被爬虫抓取到,客户端异步渲染很难被爬虫抓取
  • 所以真正的网站基本都是两者结合来做的
  • 例如京东的商品列表就采用的是服务端渲染,目的是为了 SEO 搜索引擎的优化,
  • 而它的商品评论列表为了用户体验,不需要而且不需要 SEO 优化,所以采用客户端渲染

2.2 Node.js 的模块分类

2.2.1 核心模块
Node 为 JavaScript 提供了很多服务器级别的 API ,这些 API 绝大多数背包装到一个具名的核心模块中。例如:
  • 文件操作系统的 fs 模块
  • http 构建的 http 模块,
  • pach 路径操作模块…
  • 核心模块使用方法
    var 变量名 = require('模块名')
2.2.2 第三方模块
  • art-template等很多…
  • 必须通过 npm 下载使用
2.2.3 用户自定义模块
  • 同样是通过 require 引用,require 用于加载执行模块中的代码
  • require 方法有两个作用。
    • 加载文件模块。并执行里边的代码
    • 拿到被加载文件模块导出的接口对象,
      每个文件模块都提供了一个对象,exports ,它默认是一个空对象,需要把所有需要被外部访问的成员挂载到这个空对象上。
  • 相对路径必须加 ./
  • 在 node 中,没有全局作用域,只有模块作用域(文件作用域),外部访问不到内部,内部也访问不到外部。
  • 模块之间的通信
    用 require 拿到 exports 上挂载的对象
    如果一个模块需要直接导出某个成员,而非挂载到 exports 这个对象上,
    那这个时候,必须使用这种方式 module.exports = 'add’

2.3 CommonJs 模块规范

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

  • 模块作用域
  • 使用 require 加载模块
  • 使用 exports 接口对象来导出模块成员
2.3.1 加载 require 以及加载规则
  • 语法:

    var 自定义变量名称 = require('模块')
    
  • 两个作用

    • a. 执行被加载模块的代码
    • b. 拿到被加载模块中 exports 导出的接口的对象
  • 加载规则
    + 核心模块
    + 第三方模块
    + 用户自定义模块
    + 优先从缓存加载

  • 判断模块标识
    既不是核心模块,也不是路径形式模块,先找当前文件所属目录中的 node_modules ,

    然后找引入的包名,
    
    找包名对应的 / package.json 文件
    
    找包名对应的 / package.json 文件的 main 属性
    
    main 属性中记录了 包 的入口模块
    
    然后加载使用这个第三方包 
    
    实际上加载的还是文件
    
    如果 package.json 文件不存在,或者 main 指定的入口模块是错的,
    
    则 node 会自动找该目录的 index.js ,index.js 会作为一个默认备选项
    
2.3.2 导出 expores 以及 exports 和 mudule.exports 的区别

Node 中是模块作用域,默认文件中所有成员之在当前文件中有效,
对于希望其他模块访问的成员,我们就需要把这些公开的成员都挂载到 exports 接口对象上

  • 导出多个成员 :必须在对象中

    • exports.a = 123
    • exports.b = ‘hello’
    • exports.c = function () {
      console.log(‘666’)
      }
  • 导出单个成员 :拿到的就是函数、字符串等
    以下情况会覆盖,后者会覆盖前者

    • module.exports = ‘hello’
    • module.exports = function (x,y) {
      return x + y
      }
  • module 也可以导出多个成员

      module.exports = {
        add : function () {
          return x + y 
        },
      }
    
  • exports 和 mudule.exports 的区别

    • 每个模块中都有一个 module 对象
    • module 对象中有一个 exports 对象
    • 我们可以把需要导出的成员都挂载到 module.exports 接口对象中
    • 也就是:moudle.exports.xxx = xxx 的方式
    • 但是每次都 moudle.exports.xxx = xxx 很麻烦,点儿的太多了
    • 所以 Node 为了你方便,同时在每一个模块中都提供了一个成员叫:exports
    • exports === module.exports 结果为 true
    • 所以对于:moudle.exports.xxx = xxx 的方式 完全可以:expots.xxx = xxx
    • 当一个模块需要导出单个成员的时候,这个时候必须使用:module.exports = xxx 的方式
    • 不要使用 exports = xxx 不管用
    • 因为每个模块最终向外 return 的是 module.exports
    • exports 只是 module.exports 的一个引用
    • 所以即便你为 exports = xx 重新赋值,也不会影响 module.exports
    • 但是有一种赋值方式比较特殊:exports = module.exports 这个用来重新建立引用关系的
    • 之所以说这个,是希望可以更灵活的去用它

3. Node 中的 Express

3.1 Express 是什么

  • 原生的 http 在某些方面不足以应对我们的业务需求,所以我们需要框架来加快开发效率。
  • 使用框架的目的是为了提高开发效率,让我们的代码高度统一
  • 在 Node 中有很多 Web 框架,Express 是其中之一
  • 安装 Express 后才能使用

3.2 Express 中的开放静态资源

  • 当以 /public/ 开头的时候,去 ./public/ 目录中找对应的资源,建议使用本方式
    app.use('/public/',express.static('./public/'))
  • 当省略第一个参数的时候,则可以通过省略 /pbulic 的方式访问
    app.use(express.static('./public/'))

3.3 Express 独立路由模块

  • 路由其实就是一张表,表里有映射关系。
    路由 = 请求方法 + 请求路径 + 请求处理函数。
    路由模块职责:根据不同请求方法和请求路径设置请求处理函数.
    • get :
      // 当你以 get 方法请求 / 的时候,执行对应的处理函数
      1 app.get('/' ,function (req,res) {
      2   res.send('hello,world')
      3 })
      
    • post :
      // 当你以 post 方法请求 / 的时候,执行对应的处理函数
      1 app.post('/' ,function (req,res) {
      2   res.send('got a post request')
      3 })
      
  • 创造一个路由容器
    var router = express.Router()
    
  • 把路由挂载到 router 容器中
    router.get ('/',function (req,res) {
    
    }) 
    
    router.post ('/',function (req,res) {
    
    })
    
  • 把路由容器导出
      module.exports = router
    
  • 把路由容器挂载到入口文件 app.js 或者 main.js 中
    // 加载路由文件
    var router = require('./router')
    
    // 挂载路由
    app.use(router)
    

3.4 Express 中的 Session

在 Express 这个框架中,默认不支持 Session 和 Cookie ,但我们可以使用第三方中间件:express-session 来解决

3.4.1 安装
npm install express-session
3.4.2 配置
  去 app.js 或者 main.js 中
  引包:  var session = require('express-session')
  核心代码:
  // secret: 加密字符串,它会在原有加密基础之上和这个字符串拼起来去加密,目的是为了增加安全性,防止客户端恶意伪造
  //saveUninitialized: 未初始化保存,无论你是否使用 Session,都直接默认分配一把钥匙
  
  app.use(session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true
  }))
3.4.3 使用

当把这个插件配置好之后,通过 req.session 来访问和设置 session 成员。Session是一个对象。

  • 添加 Session 数据:req.session.foo = ‘bar’
  • 访问 Session 数据:req.session.foo
  • 通过 Session 记录用户登录状态

3.5. Express 中的中间件(mideleware)

3.5.1 安装
  • 处理请求的实际上是个函数,中间件本身是一个方法,改方法接受三个参数,
    • Request 请求对象
    • Response 响应对象
    • next 下一个中间件
      当一个请求进入一个中间件之后,如果不调用 next 则会停留在当前中间件, next 是一个方法,用来调用下一个中间件
3.5.2 配置
  • 在 app.js 中配置处理 404 的中间件
    在挂载路由之后

       ```
       app.use(function (req,res) {
         res.render('404.html')
       })
       ```
    
  • 在 404 之后,配置全局处理中间件

    // 四个参数一个都不能少
    app.use(function (err,req,res,next) {
      res.status(500).json({
        err_code: 500,
        message: err.message
      })
    })
    
3.5.2 使用
  上边所有的 err 处理都改成:
  ```
  if (err) {
    next(err)
  }
  ```
  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值