手把手小白入門Node.js

226 阅读16分钟

Nodejs基本介绍

目标

  • 掌握Node.js的基本概念;
  • 了解Node.js在前端和后端领域中的作用

提问:前端要学什么编程语言?后端会用什么编程语言?(phy, python, java.....)

提问:可以用js语言实现后端的功能吗?

image-20210319102258500.png

Node.js是什么

Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时

名词解释

  • chrome V8引擎:

    • chrome: chrome浏览器

    • 引擎:用来解析和执行代码的工具。

      汽车发动机引擎可以将燃油转成动力; JS解析引擎可以将代码转成最终的效果

    • V8:项目的代号

  • 运行时:理解为一个容器,用来运行代码的环境;

示意图

image-20210908111808494.png

大白话: nodejs提供了一个运行环境,我们在这个环境中可以运行js代码,这个环境是基于V8引擎来实现的。

Node.js可以做什么

Node.js 作为一个 JavaScript 的运行环境,仅仅提供了基础的功能和 API,而基于 Node.js程序员实现了很多强大的工具和框架。

具体来说:

  • 后端API接口。基于Node.js环境 + Express框架
  • 桌面应用。基于Node.js环境 + Electron 框架
  • 操作数据库。基于Node.js环境 + MySql包 读写和操作数据库
  • 实用的命令行工具。基于Node.js环境,实现的 vuecli,webpack等
  • etc...

总之,Node.js 是大前端时代的“大宝剑”,有了 Node.js 这个超级 buff 的加持,前端程序员的行业竞争力会越来越强!

Node.js为什么要学习

  • 给学习前端框架,工具打下基础

  • 更深入的模块化

  • 了解服务器后端工作

  • 增加职场竞争力

image-20210319103423302.png

Node.js的学习内容

它只是一个环境,不是一门语言(不需要学习新语言),我们要学习:

  • Node.js内置API模块(fs, path等....)
  • 第三方API模块

下装安装Nodejs

目标

在官网上下载并安装Nodejs; 会检查本地Nodejs是否安装完成;

下载

上官网: 英文 中文

image.png

版本说明:

  • LTS: 长期稳定版(Long Term Support)。 项目开发建议使用长期稳定版
  • Current: 最新尝鲜版 。最新版包含了一些新功能,如果想学习最新的功能,则可以使用该版本。最新版可能会有一些未知的bug。

下载

点击左侧的按钮(有LTS标识的那个),会立即下载,注意:不同系统选择对应的安装文件。

安装

  1. 找到你下载的安装包(不同的版本有不同的安装包)

image.png

  1. 双击安装文件开始安装

    傻瓜式安装,一路 next 即可

注意:

  • 建议安装目录所使用英文路径 (不要安装在类似于 d:/软件/node)最好不要修改路径 选择默认 后期插件或其他会莫名其妙报bug
  • 安装完成之后, 它不会在桌面出现快捷图标

测试是否安装成功

打开终端,在终端的命令窗口中输入 node -v 命令,按下回车键。

如果在终端窗口中能够打印出 Node.js 的版本号,就证明 Node.js 已经安装成功,完全满足后续的学习需求。

什么是终端?

终端

(英文:Terminal)是专门为程序员设计的,通过输入命令来操作电脑的一种方式(装 X 神器)。

作为程序员,非常有必要学习一些常用的终端命令,来辅助我们更好的操作与使用计算机。

Windows 系统快速打开终端的三种方式

  1. cmd窗口(window+R, --->运行-->录入cmd,回车)

image.png

image.png 0. 在资源管理器的地址栏中,输入 cmd 后直接回车,即可打开终端

  1. 任意位置,shift+右键

image.png

image.png

Mac 电脑快速打开终端的方式:由于没有Mac 就不做演示啦

①使用快捷键 Command(⌘) + 空格键 打开搜索窗口

②在搜索窗口中输入 terminal 并回车,即可打开终端

在Node环境下运行js代码

我们没有接触node.js以前,js代码都是在浏览器中运行的,现在开始学习nodejs后,我们有了第二个可以运行js代码的环境。下面来学习如何去运行。

目标

掌握在NodeJS环境下运行js代码的步骤

步骤:

  1. 准备好要被执行的js文件
  2. 在命令行工具中写命令来运行这个文件

准备一个JS文件

请事先准备好一个js文件。例设这里的路径是:d:/src/index.js

具体内容如下:

// d:/src/index.js
var a = 1;
console.info(a + 2);

打开命令行工具,运行这个文件

格式

node 要执行的文件的路径

注意:node 的后面有一个空格

示例

例如:
node 01.js   # 01.js就是当前目录下
node a/01.js # 01.js在目录a下面

小结

  1. 运行js代码的格式:

    格式: node 文件的位置

  2. 注意:

    最好是在当前文件所在目录下来运行这个js文件

学习常用的命令行下的命令及按键

命令及键盘按键

一共有9个

1)node 空格 某个js文件         // 调用 node 程序,运行某个js文件
​
(2)clear  或者  cls            // 清空界面
​
(3)ls 或者 dir                 // 查看列表(list)
​
(4)cd 目录名                   // 进入到目录中去
​
(5)cd ..                      // 返回上一级目录
​
(6)cd \                                     // 直接回到根目录
                   
(7)Ctrl+C                     // 停止 Node 程序
​
(8)输入部分文件名后按下 Tab 键  // 补全文件名 或 目录名, 多次tab会进行切换
​
(9)↑ ↓ 上下箭头                // 切换历史输入

复制粘贴

在小黑窗中复制内容:选中内容,再点鼠标右键

把粘贴板中的内容复制到小黑窗: 点鼠标右键

课堂练习

  1. 下载安装nodejs
  2. 检查node的版本
  3. 学习常用的命令行下的命令及按键

Nodejs和浏览器端的区别

目标

了解NodeJs和浏览器端的区别

image-20200614000309727.png

image-20200614001440512.png

在浏览器端

javascript由三部分组成:ECMAScript + BOM + DOM

es6 ==> ECMAScript 6.0

在nodejs端

ECMAScript + 内置模块(fs, http, path,.....)。在nodejs中是没有BOM、DOM、window,但使用ECMAScript是通用的

NodeJS中没有DOM,也没有BOM,也没有window对象。

ECMAScript

ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,European Computer Manufacturers Association)通过ECMA-262组织的标准化的脚本程序设计语言。

ECMAScript是javascript语言的一个标准。它约定了:如何定义变量,函数,运算,数组,内置对象等等。

小结

image-20210908152129610.png

相同点:

  • 都是可以运行js代码的容器
  • 都可以运行ECMAScript

不同点

  • 各有不同的API: 在nodejs下 就不能写DOM, BOM,也不能用window对象了
  • 运行代码的方式不一样

Nodejs中的模块分类

目标

了解nodejs中的模块分类

image-20210318113259661.png

每个模块都是一个独立的文件。每个模块都可以完成特定的功能,我们需要时就去引入它们,并调用。

nodejs模块的分类

  • 核心模块

    • 就是nodejs自带的模块,在安装完nodejs之后,就可以直接使用啦。
    • 相当于学习js时使用的alert,confirm等函数。
  • 第三方模块

    • 其他程序员写好的模块。nodejs生态提供了一个专门的工具npm来管理第三方模块,后面我们会专门讲到。
    • 相当于别人写好的函数或者库。例如JQuery库,artTemplate等。
  • 自定义模块

    • 程序员自己写的模块。
    • 相当于我们在学习js时的自定义函数

核心模块的基本使用

目标

了解核心模块的概念,掌握核心模块的基本使用方法

核心模块

核心模块就是 Node 内置的模块,安装完Nodejs之后,开箱即用

  • 每个核心模块都有唯一的标识名称

  • 核心模块有很多个,每个模块都有直接的作用,这里有文档

  • 使用步骤都是先导入,再使用

image-20210908160221202.png

来进行获取。每一个核心模块基本上都是暴露了一个对象,里面包含一些方法供我们使用。一般在加载核心模块的时候,变量(或常量)的起名最好就和核心模块的标识名同名。

例如:const fs = require('fs')

const path = require('path')        // 1. 导入模块
const str = path.join('a', 'b')     // 2. 使用模块
console.log(str)

用require来导入模块

每个核心模块有自己的功能,想用哪个就导入哪个。

语法格式

 const 模块的接收名称 = require('模块名字')

其中:

  1. 模块的接收名称可以自定义,只要是合法的变量名即可。例如:
const 123fs = require('fs') // 错误,不能以数字开头const p = require('path') // 正确
  1. const 。可以使用var、let,但是建议使用const,因为我们不希望它被改变。名字不必大写成FS,一般也就叫fs这个名字。

使用模块

导入成功之后:

带着自己的目标,查官方手册。

fs模块

fs模块(fs是 FileSystem的简写)是Node.js用来进行文件操作的模块,它属于核心模块。你引入之后就可以直接使用了。

官方手册:nodejs.cn/api/fs.html api.nodejs.cn/

核心模块的使用步骤:

  1. 引入模块

    // 引入模块
    const fs = require('fs');
    // 可以使用var、let,但是建议使用const,因为我们不希望它被改变。
    // 名字不必大写成FS,一般也就叫fs这个名字。
    
  2. 调用api实现自己的要求

    fs.apiName()
    

fs模块中操作文件(或者文件夹)的方法,大多都提供了两种选择:

  • 同步版本的
  • 异步版本的

小结

核心模块是指fs

fs-readFile-异步格式

目标

写代码去读出文件内容,并打印在屏幕上

格式

fs.readFile('文件路径'[,选项], function (err, data) {
  if (err) {
    console.log('有错误,错误内容是', errr)
  } else {
    console.log('读入文件正确,内容是', data)
  }
});

说明:

  • 参数1:文件路径。 相对路径和绝对路径均可。

  • 参数2: 配置项,可不写。主要用来配置字符集。一般可设置为utf8,如果不设置该参数,文件内容会Buffer形式返回。

  • 参数3: 回调函数。这个回调函数在读完文件后自动被自动调用,并传入 err 和 data

    • 如读取成功,回调函数中的两个参数分别是:

      • err: null

      • data: 文件内容。如果不设置参数2,则返回二进制数据。可以使用 toString() 方法将二进制数据

        转为正常字符串

    • 如读取失败,回调函数中的两个参数分别是:

      • err: 错误对象
      • data: undefined

示例1:读文本内容

const fs = require("fs")
fs.readFile('文件路径',(err, data) => {
  if (err) throw err;
  console.log(data);
});

上面的data将会是一个Buffer对象类似于数组,它的元素为16进制的两位数,它表示读出来的内容在计算机中的二进制格式。它有一个toString()方法,可以用来把内容以UTF-8的格式转成字符串。

示例2:读文本内容-指定编码格式

const fs = require("fs")
fs.readFile('文件路径', "utf8", (err, data) => {
  if (err) throw err;
  console.log(data);
});

示例3:读入图片文件

const fs = require("fs")
fs.readFile('./img/1.jpg',  (err, data) => {
  if (err) throw err;
  console.log(data);
});

并不是它所有的文件都应该转成字符串的

示例4:体会异步的效果

异步的

const fs = require("fs")
console.log(1)
fs.readFile('文件路径', "utf8", (err, data) => {
  if (err) throw err;
  console.log(data);
});
console.log(2)

并不是它所有的文件都应该转成字符串的

练习

  1. 读文件试一试

    • 不同类型的:.txt. , .js, .jpg, .avi(读一个很大电影)
    • 不写utf8,写utf8
    • 体会一下异步

fs-readFile-观察并处理错误

nodejs中的错误界面相比浏览器中的错误来说,并不友好。

如果读文件有错误

fs.readFile('./02.txt12112',function(err, data) {
  // 如果读文件出错了(可能的原因:路径不对,文件不存在....)
  // err的值就不是null
​
  // if(出错)  {
  //   处理错误
  // } else {
  //   正常
  // }
  if(err){
    // throw: 抛出
    // throw 这个命令用来告诉node.js,这里有一个错误
    //       停止后续代码的执行
    console.log(err)
    return
    // throw err;
​
    // 尽早返回
  }
  console.log('读出的内容是', data)
})

在node.js中遇到的错误之后,应该观察错误说明

fs-readFile-同步格式

格式

const fs = require("fs")
let rs = fs.readFileSync('文件路径',"utf8");
console.log(rs)
  • api的名字后面有Sync(async是异步的,sync表示同步的)
  • 不是通过回调函数来获取值,而是像一个普通的函数调用一样,直接获取返回值

捕获同步格式中的错误对象

如果读成功,则会获取读出来的数据,如果失败了,则会中断后续所有的代码执行。

console.log(1)
let res = fs.readFileSync('errorPath.js')
console.log(res)
console.log(2)

解决方案:用try. catch 结构

try {
  const fs = require("fs")
    let rs = fs.readFileSync('文件路径',"utf8");
    console.log(rs)
} catch(err) {
  console.log(err)
}

fs-writeFile-文件覆盖写入

覆盖写入 writeFile

功能:向指定文件中写入字符串, 如果没有该文件则尝试创建该文件。它是覆盖写入:会把文件中的内容全部删除,再填入新的内容。

格式:

fs.writeFile(pathName, content, option, (err)=>{});
// 参数1: 要写入的文件路径 --- 相对路径和绝对路径均可,推荐使用绝对路径
// 参数2: 要写入文件的内容
// 参数3: 配置项,设置写入的字符集,默认utf-8
// 参数4: 写入完成后触发的回调函数,有一个参数 --- err (错误对象)

示例1: 写入.txt文件

const fs = require('fs')
fs.writeFile('./a.txt', 'hello world! \n 换一行', err => {
  if (err) {
    console.info(err)
    throw err
  }
})

示例2: 写入json

稍微把问题提升一下,问: 如何把数据写入文件中?

const fs = require('fs')
​
const data = [{name: '小王', age: 20}]
fs.writeFile('./a.txt', data, err => {
  if (err) {
    console.info(err)
    throw err
  }
})

上面的写法会出错: data不是一个字符串或者是Buffer

正确做法是用JSON转一下。

const fs = require('fs')
​
const data = [{name: '小王', age: 20}]
fs.writeFile('./a.txt', JSON.stringify(data), err => {
  if (err) {
    console.info(err)
    throw err
  }
})

fs-appendFile-文件追加写入

功能

向指定文件中写入字符串(追加写入), 如果没有该文件则尝试创建该文件。

格式

fs.appendFile(pathName, content, option, callback);
// 参数1: 要写入的文件路径 --- 相对路径和绝对路径均可,推荐使用绝对路径
// 参数2: 要写入文件的字符串
// 参数3: 配置项,设置写入的字符集,默认utf-8
// 参数4: 写入完成后触发的回调函数,有一个参数 --- err (错误对象)

示例

const fs = require('fs')
​
fs.appendFile('./a.txt', '\n 为天地立命', err => {
  if (err) {
    console.info(err)
    throw err
  }
})

\n : 表示换行

路径问题-相对路径的隐患

在读取文件时,使用相对路径是容易出问题的

下面我们来看会出什么问题。

素材准备

假设有如下两个文件,它们所处的目录及文件名如下所示:

|-day02
|------02code-nodejs
|--------------------03.fs.js
|--------------------03.fs.txt

03.fs.js代码的作用是读出03.fs.txt中的内容,并显示出来,它的代码是这样的:

// 03.fs.js
const fs = require('fs');
fs.readfilesync("./03.fs.txt",'utf8'); 
//注意这里对03.fs.txt的访问使用的是相对"fs.js" 本身的路径

由于03.fs.js和要读取的目标03.fs.txt是在同级目录下,所以可以写相对路径。

运行代码

想要运行03.fs.js这个文件有多种方式,根据当前处在的位置不同:

  • A. 如果终端中的路径定位在day02/02code-nodejs目录下,则通过node 03.fs.js可以顺序执行
  • B. 如果终端中的路径定位在day02目录下,则通过:node 02code-nodejs/03.fs.js 能成功执行.js文件,但是却找不到文件路径了。

原因分析

我们在fs中读取文件时,由于使用的是相对路径,所以在读这个文件的时,nodejs会去:

运行命令的小黑窗的路径 + 代码中的相对路径 找它。

所以上述代码中:

  • A方案在运行时,找到的文件是day02/02code-nodejs/03.fs.txt,它可以找到文件
  • B方案在运行时,找到的文件是day02/03.fs.txt,它就找到不文件了

解决方法

就是在操作文件时,使用绝对路径来定位文件。

D:/node-learn/02-代码/day01/js/info.txt

小结

在读写文件时,尽量不要采用相对路径,它容易出问题。

路径问题-获取绝对路径

目标

掌握 __dirname__filename的用法,并在操作文件路径时正确使用

__dirname,__filename

__filename 和 __dirname 是 Node.js 内置的全局变量

  • 特点是:不用声明就能直接使用

  • 全局变量的含义是:

    • 变量:它们的值是变化的。在不同的文件中值就不同。
    • 全局:在任意地方都可以直接使用。
  • 其中:

    __filename 表示当前文件的完整路径(包含文件名)

    __dirname 表示当前文件的完整存放目录(不包含文件名)

测试使用,在任意代码的任意位置

console.log(__dirname)
console.log(__filename)

在文件操作时,使用绝对路径

只需要在读入文件时,在路径前面拼接上:

// 拼接html5.jpg的绝对路径
// 1) 找到当前文件夹的绝对路径
console.log(__dirname)
const fs = require('fs')
// 2) 加上 html5.jpg
const filePath = __dirname + '\html5.jpg'
// 走一步,看一步
console.log(filePath)
// 3)读入文件
fs.readFile(filePath,function(err, data) {
  if(err) {
    console.log(err)
    return
  }
  console.log(data)
})
​
​

path模块

作用

path也是node中的核心模块,作用是用来处理路径问题:拼接,分析,取后缀名等等。

文档地址

使用步骤

  1. 引入模块
const path = require('path')
  1. 使用模块

常用的api

  • path.basename():此方法返回 path 的最后一部分。一般可用来获取路径中的文件名。
  • path.join(): 路径拼接
  • path.extname(): 获取后缀名

示例

path.basename('/foo/bar/baz/asdf/quux.html');// 返回: 'quux.html'
path.basename('/foo/bar/baz/asdf/quux.html', '.html');// 返回: 'quux'
path.dirname('/foo/bar/baz/asdf/quux');// 返回: '/foo/bar/baz/asdf'
path.extname('index.html');// 返回: '.html'

注意:不考虑其中地址是否真的存在,只是单纯调用方法,获取结果。

路径问题-使用path模块解决文件读写中的路径拼写

// 拼接html5.jpg的绝对路径
// 1) 找到当前文件夹的绝对路径
console.log(__dirname)
// 2) 加上 html5.jpg
const fs = require('fs')
const path = require('path')
const filePath = path.join(__dirname, 'html5.jpg')
// const filePath = __dirname + '\html5.jpg'
// 走一步,看一步
console.log(filePath)
​
fs.readFile(filePath,function(err, data) {
  if(err) {
    console.log(err)
    return
  }
  console.log(data)
})
​
​

附:path模块常用方法列表

方法作用
path.basename(path[, ext])获取返回 path 的最后一部分(文件名)
path.dirname(path)返回目录名
path.extname(path)返回路径中文件的扩展名(包含.)
path.format(pathObject)将一个对象格式化为一个路径字符串
path.join([...paths])拼接路径
path.parse(path)把路径字符串解析成对象的格式
path.resolve([...paths])基于当前工作目录拼接路径

附:fs模块中的常用方法

API作用备注
fs.access(path, callback)判断路径是否存在
fs.appendFile(file, data, callback)向文件中追加内容
fs.copyFile(src, callback)复制文件
fs.mkdir(path, callback)创建目录
fs.readDir(path, callback)读取目录列表
fs.rename(oldPath, newPath, callback)重命名文件/目录
fs.rmdir(path, callback)删除目录只能删除空目录
fs.stat(path, callback)获取文件/目录信息
fs.unlink(path, callback)删除文件
fs.watch(filename[, options][, listener])监视文件/目录
fs.watchFile(filename[, options], listener)监视文件
fs.existsSync(absolutePath)判断路径是否存在

\