nodejs笔记

本文介绍了Node.js中如何在环境中执行JS代码,包括版本控制、fs模块的读写文件操作,以及path模块的路径处理。接着讲解了http模块创建Web服务器的基本步骤,强调了request和response对象的使用。最后,文章讨论了Node.js的模块化机制,包括module.exports和exports的区别,以及npm包的管理,如安装、卸载和包的分类。
摘要由CSDN通过智能技术生成

一、在nodejs环境中执行js代码

输入node + 要执行的js文件的路径

1、node版本控制使用

1.1 n

安装n:npm install -g n

 查看n版本:n --version

查看当前安装过的node版本:n list 

安装制定的node版本:n 版本号 

删除node版本:n rm 版本号 

切换当前node版本:输入n,选择你需要的node版本

1.2 nvm

1. nvm 版本
nvm --version
2. 安装指定版本node
nvm install v16.16.0
3. 切换指定node版本
nvm use 16.16.0
4. 查看本地的所有node版本
nvm list
5. 删除指定版本node
nvm uninstall v16.16.0

2、Node 包管理

查看各个包的国内镜像地址(省去了去查找源的步骤)

2.1 安装

npm i -g nrm

2.2 查看各个源

nrm ls

2.3 切换源

nrm use taobao

2.4 查看当前使用的源

nrm config get registry

二、fs文件系统模块

fs.readFile()方法,用来读取指定文件中的内容

fs.writeFile()方法,用来向指定的文件中写入内容

如果要在js代码中,使用fs模块来操作文件,则需要导入(require)模块

const fs = require('fs')

1、fs.readFile()的语法格式:

fs.readFile(path[,options],callback)

path: 文件路径

options:用什么编码格式读取

callback:读取完成后,通过回调来拿到读取的结果


// 导入fs模块
const fs = require('fs');
// 调用fs.readFile()方法来读取文件
/**
 * 参数1:文件的存放路径
 * 参数2:读取文件的时候采取的编码格式
 * 参数3:拿到读取成功和失败的结果(err,dataStr)
 *      如果读取成功,err的值为null,dataStr为读取后的结果
 *      如果读取失败,err为错误对象,dataStr的值为undefined
 */
fs.readFile('./test.js','utf-8',function(err,dataStr) {
    // 如果读取成功,则err的值为null
    console.log(err);
    console.log('---------------');
    // 成功的结果
    console.log(dataStr);
})

2、向指定文件中写入内容

fs.writeFile()的语法格式:

fs.writeFile(file,data[,options],callback)

file:文件路径

data:要写入的内容


const fs = require('fs');
/**
 * 回调函数:
 * 文件写入成功:err值为null,suc是undefined
 * 文件写入失败:err为错误对象
 */
fs.writeFile('./test.txt', 'hello nodejs', function(err,suc) {
    // 如果文件写入成功,error的值为null
    console.log(err);
    console.log('------------------');
    console.log(suc);
})

fs模块-路径动态拼接的问题

读写时出现路径拼接错误问题,是因为提供了./或../开头的相对路径,如果要解决这个问题,可以直接提供完整文件存放的路径


fs.readFile('/Users/tian/Desktop/node/成绩整理demo/成绩.txt','utf-8', function() {})

但是文件路径太长不利于维护,nodejs提供了解决方法(__dirname,是双下划线)


fs.readFile(__dirname + '/test.js','utf8',function() {})
// 可以打印一下__dirname
console.log(__dirname);  // 是当前文件所处目录

三、path路径模块

1、path.join()方法:用来将多个路径片段拼接成一个完整的路径字符串(尽量不要使用+号进行拼接)

2、path.basename()方法:用来从路径字符中,将文件名解析出来

3、path.extname()方法:获取路径中的文件扩展名

如果要使用path路径模块,也是需要导入的


const path = require('path')

path.join()语法格式:

path.join(路径1,路径2) 会有一个返回值,字符串类型


const path = require('path')
const pathStr = path.join('/a','/b/c','../','./d','e')
// ../会抵消前面的路径
console.log(pathStr);
// 输出结果:/a/b/d/e

path.basename()语法格式:

path.basename(path[,ext])

参数1 path:文件路径

参数2 ext:文件后缀名


const path = require('path')
// 文件的存放路径
const fpath = '/path文件路径/index.html'
var fullName = path.basename(fpath);
console.log(fullName);  // index.html
const fExt = path.basename(fpath, '.html');
console.log(fExt);  // index
// 如果有第二个参数,会把文件的后缀名去掉

path.extname()语法格式:

path.extname('文件路径')

四、http模块

http模块,是nodejs提供用来创建web服务器的模块。通过http.createServe()方法,就能把一台普通的电脑,变成web服务器,从而对外提供web资源服务。

服务器ip 127.0.0.1,域名:localhost

端口号:一个服务器,可以运行多个web服务,每个web服务都对应一个唯一的端口号。在实际应用中,url中的80端口是可以省略的

创建最基本的web服务器

1、创建web服务器的基本步骤:

1.1:导入http模块

1.2:创建web服务器实例,调用http.createServer()方法,可以快速的创建一个web服务器实例

1.3:为服务器实例绑定request事件,监听客户端的请求(绑事件类似于,jq写法)

1.4:启动服务器,调用服务器实例的.listen()方法,即可启动当前web服务器实例


// 1.1导入模块
const http = require('http')
// 1.2创建web服务器实例
const serve = http.createServer()
// 1.3绑定request事件
serve.on('request', (req, res) => {
    // 只要有客户端来请求服务器,就会触发request事件,从而调用这个事件处理函数
    console.log('有人访问服务器');
})
// 1.4 启动web服务器
// 调用serve.listen(端口号, 回调)方法
serve.listen(80, () => {
    console.log('http serve running at http://127.0.0.1');
})

2、步骤3的req请求对象:

只要服务器收到了客户端的需求,就会调用通过serve.on()为服务器绑定的request事件处理函数。

如果想在事件处理函数中,访问与客户端相关的数据或属性,可以使用如下的方法:


const http = require('http');
const serve = http.createServer();
serve.on('request', (req) => {
    // req是请求对象,它包含了与客户端相关的数据和属性,例如:
    // req.url:是客户端请求的url地址
    // req.method:是客户端的请求类型
    console.log(`url is ${req.url}, method is ${req.method}`);
})6
serve.listen(80, () => {
    console.log('http serve running at http://127.0.0.1');
})

3、步骤3的res响应对象

在服务器的request事件处理函数中,如果想访问与服务器相关的数据或属性,可以使用如下的方式:


const http = require('http');
const serve = http.createServer();
serve.on('request', (req, res) => {
    const str = `url is ${req.url}, method is ${req.method}`;
    console.log(str);
    // res.end() 方法的作用:
    // 向客户端发送指定的内容,并结束这次请求的处理过程
    res.end(str)  // str为响应的内容
})
serve.listen(80, () => {
    console.log('http serve running at http://127.0.0.1');
})

4、解决中文乱码问题

当调用res.end()方法,向客户端发送中文内容的时候,会出现乱码的问题,此时,需要手动设置内容的编码格式:


serve.on('request', (req, res) => {
    const str = `url is ${req.url}, method is ${req.method}`;
    // 为了防止中文乱码的问题,需要设置响应头 Content-Type 的值为 text.html;charset=utf-8
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
    res.end(str)
})

五、模块化

1、模块的分类:

内置模块:由nodejs官方提供的,例如fs、path、http等

自定义模块:用户创建的每个js文件,都是自定义模块

第三方模块:由第三方开发出来的模块,使用前需要先下载

2、加载模块:

使用require()方法,可以加载需要的模块进行使用。

3、模块作用域:

在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域。

好处:防止了全局变量污染的问题

4、向外共享模块作用域中的成员

(1)module对象:

在每个自定义模块中都有一个module对象,它里面存储了和当前模块有关的信息


// 可以打印module
console.log(module)

(2)module.exports对象:

在自定义模块中,可以使用module.exports对象,将模块内的成员共享出去,供外界使用。

外界用require()方法导入自定义模块时,得到的就是module.exports所指向的对象。

在一个自定义模块中,默认情况下,module.exports = {},所以没有导出内容的时候,打印为空对象,当在向module.exports对象上挂载了属性的时候,打印的结果就不是空对象了。


// 自定义模块
const msg = '加载了自定义模块'
// 向module.exports对象上挂载msg属性
module.exports.msg = msg;

module.exports.sayHello = function() {
    console.log('Hello')
}

共享成员要注意的是:使用require()方法导入模块时,导入的结果,永远以module.exports指向的对象为准。


// 向module.exports对象上挂载属性方法
module.exports.username = 'tian'
module.exports.wifi = function() {
    console.log('WIFI FAN');
}

// 让module.exports指向一个全新的对象,将上面的覆盖掉了
module.exports = {
    nickName: 'wifi歪f',
    sayLove() {
        console.log('I love wifi');
    }
}

const mokuai = require('./模块化/index')
console.log(mokuai);
// 输出的内容为:{ nickName: 'wifi歪f', sayLove: [Function: sayLove] }

(3)exports对象:

由于module.exports写起来比较复杂,node提供了exports对象。默认情况下,exports和module.exports指向同一个对象。最终共享的结果,还是以module.exports指向的对象为准。


exports.username = 'tian'
exports.wifi = function() {
    console.log('WIFI FAN');
}

(4)module.exports 与 exports的使用误区:

牢记:require()方法导入模块时,导入的结果,永远以module.exports指向的对象为准。

例1:


exports.username = 'tian'
module.exports = {
    age: 19
}
// 打印结果为  { age: 19 }

例2:


module.exports.username = 'tian'
exports = {
    age: 19
}
// 打印结果为  { username: 'tian' }
// export指向了一个新的对象,但是module.exports还是指向的是原来的对象,导入的结果,永远以module.exports指向的对象为准。

例3:


exports.username = 'tian'
module.exports.age = 20 
// 打印结果为  { username: 'tian', age: 20 }

为了防止混乱,建议不要在同一个模块中同时使用exports和module.exports。

5、nodejs中模块化规范

nodejs遵循了CommonJS模块化规范,CommonJS规定了模块的特性和各模块之前如何相互依赖。

CommonJS规定:

每个模块内部,module变量代表当前模块。

module变量是一个对象,它的exports属性(即module.exports)是对外的接口。

加载某个模块,其实就是加载该模块的module.exports属性。require()方法用于加载模块。

六、npm与包

1、包:nodejs中的第三方模块叫做包。

2、在哪找包:npm | Home 在哪下包:http://registry.npmjs.org/

3、如何下载包:

在安装nodejs的时候就已经安装了npm包管理工具。

安装包的命令:npm install 包完整的名字

简写: npm i 包完整的名字

4、初次装包后:会多了一个node_modules的文件夹和package-lock.json的配置文件。

node_modules文件夹:用来存放已安装到项目中的包。require()导入第三方包时,就是从这个目录中查找并加载包的。

package-lock.json配置文件:用来记录node_modules目录下的每一个包的下载信息,比如包的名字,版本号,下载地址。

5、安装指定版本的包:

在包名后面加@符号指定具体的版本:npm i moment@2.22.2

6、package.json包管理配置文件

npm init -y 快速创建package.json文件

7、dependencies节点:

在创建package.json时是没有dependencies节点的,当安装了包后会自动生成,用来记录安装了哪些包。

8、卸载包:

npm uninstall 包名

9、devDependencies节点:

如果某些包只在项目开发阶段会用到,在项目上线之后不会用到,则建议把这些包记录到devDependencies节点中,与之对应的,如果某些包在开发和项目上线之后都需要用到,则建议把这些包记录到dependencies节点中。

使用如下命令,可以将包记录到devDependencies节点中:


// 安装指定包,并记录到devDependencies节点中
npm i 包名 -D
// 上面是简写,完整写:包名和--save-dev顺序可以换
npm install 包名 --save-dev 

10、切换npm的下包镜像地址


# 查看当前的下包镜像源
npm config get registry
# 将下包镜像源切换为淘宝镜像源
npm config set registry=https://registry.npm.taobao.org/
# 检查镜像源是否下载成功
npm config get registry

11、包的分类:

(1)项目包:安装在node_modules中的包

项目包又分为:

开发依赖包:被记录到devDependencies节点中的包

核心依赖包:被记录到dependencies节点中的包

(2)全局包

在执行npm install命令时,如果提供了-g参数,则会把包安装到全局。

12、规范的包结构:要符合3个要求

(1)包必须以单独的目录存在

(2)包的顶级目录下要必须包含package.json这个包管理配置文件

(3)package.json中必须包含name、version、main这三个属性,分别代表包的名字、版本号、包的入口。

七、模块的加载机制:

模块在第一次加载后会被缓存。多次调用同一个模块的代码不会被执行多次,从而提高了模块的加载效率。

1、内置模块的优先级最高,先加载内置模块

2、使用requie()加载自定义模块时,必须以./或../开头的路径标识符。如果没有这样的标识符,node会把它当作内置模块或第三方模块进行加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值