Nodejs_node基础

Node基础

一、给Node传递参数

在命令行执行js文件时,可以在命令后面直接写参数传入参数,传入的参数会存储到属性process内置对象argv当中

console.log(process.argv);
process.argv.forEach(item => {
  console.log(item);
});

二、Node的输出

  • console.log :最常用的输入内容的方式:console.log
  • console.clear :清空控制台:console.clear
  • console.trace :打印函数的调用栈:console.trace

三、全局对象

1.常见全局对象
  • process对象:process提供了Node进程中相关的信息
  • console对象:提供了简单的调试控制台
  • 定时器函数:在Node中使用定时器有好几种方式:
    • setTimeout(callback, delay[, …args]):callback在delay毫秒后执行一次;
    • setInterval(callback, delay[, …args]):callback每delay毫秒重复执行一次;
    • setImmediate(callback[, …args]):callback I/O事件后的回调的“立即”执行;
    • process.nextTick(callback[, …args]):添加到下一次tick队列中;
2.特殊全局对象

这些全局对象可以在模块中任意使用,但是在命令行交互中是不可以使用的;

  • _ _ dirname:获取当前文件所在的路径。
  • _ _ filename:获取当前文件所在的路径和文件名称。
3.global对象

global是一个全局对象,事实上前端我们提到的process、console、setTimeout等都有被放到global中。

类似于浏览器中的window对象。

四、模块化

1.CommonJs

Node中对CommonJS进行了支持和实现,让我们在开发node的过程中可以方便的进行模块化开发:

  • 在Node中每一个js文件都是一个单独的模块;
  • 这个模块中包括CommonJS规范的核心变量:exports、module.exports、require;
  • 我们可以使用这些变量来方便的进行模块化开发;

exporst导出:

  • 1.exports是一个对象,我们可以在这个对象中添加很多个属性,添加的属性会导出;
exports.name = name;
exports.age = age;
  • 2.另一个文件中导入
const bar = require('./bar')
console.log(bar.name)
console.log(bar.age)

module.exports:

  • Node中真正用于导出的其实根本不是exports,而是module.exports。
  • module对象的exports属性是exports对象的一个引用

require:

总结比较常见的查找规则:导入格式如下:require(X)

  • 情况一:X是一个核心模块,比如path、http p 直接返回核心模块,并且停止查找.
  • 情况二:X是以 ./ 或 …/ 或 /(根目录)开头的.

第一步:将X当做一个文件在对应的目录下查找;

  • 1.如果有后缀名,按照后缀名的格式查找对应的文件
  • 2.如果没有后缀名,会按照如下顺序:
    • 直接查找文件X
    • 查找X.js文件
    • 查找X.json文件
    • 查找X.node文件

第二步:没有找到对应的文件,将X作为一个目录 ,查找目录下面的index文件

  • 1> 查找X/index.js文件
  • 2> 查找X/index.json文件
  • 3> 查找X/index.node文件

如果都没有找到,那么报错:not found

  • 情况三:直接是一个X(没有路径),并且X不是一个核心模块,回去每个文件目录的node_modules中寻找,直到寻找到根目录。

模块的加载过程

  • 结论一:模块在被第一次引入时,模块中的js代码会被运行一次
  • 结论二:模块被多次引入时,会缓存,最终只加载(运行)一次(每个模块对象module都有一个属性:loaded。为false表示还没有加载,为true表示已经加载;)
  • 结论三:如果有循环引入(图结构这种)图结构在遍历的过程中,有深度优先搜索(DFS, depth first search)和广度优先搜索
2.Node对ES Module的支持
  • 方式一:在package.json中配置 type: module(后续学习,我们现在还没有讲到package.json文件的作用)
  • 方式二:文件以 .mjs 结尾,表示使用的是ES Module;

五、常见内置模块

1.path
(1)从路径中获取信息
  • dirname:获取文件的父文件夹;
  • basename:获取文件名;
  • extname:获取文件扩展名;
const path = require('path')

// 1.获取路径的消息
const filepath = '/User/why/abc.txt'

console.log(path.dirname(filepath));// /User/why
console.log(path.basename(filepath));// abc.txt
console.log(path.extname(filepath));// .txt
(2)路径的拼接
  • join路径拼接
  • resolve路径拼接

**区别:**join与resolev的区别,resolve会判断拼接路径字符串中,是否有以/或./或…/开头的路径,有的话则会在路径开头打印根路径或当前路径或上一级路径

const basepath = '/User/why'
const filename = 'abc.txt'
const file1path = path.join(basepath, filename);
console.log(file1path);//  \User\why\abc.txt
const file2path = path.resolve(basepath, filename);
console.log(file2path);//  D:\User\why\abc.txt

const basepath = './User/why'
const filename = 'abc.txt'
const file1path = path.join(basepath, filename);
console.log(file1path);//  User\why\abc.txt
const file2path = path.resolve(basepath, filename);
console.log(file2path);// D:\Microsoft VS Code web Node\01.Node基础\03.常见的内置模块\path\User\why\abc.txt

const basepath = '../User/why'
const filename = 'abc.txt'
const file1path = path.join(basepath, filename);
console.log(file1path);//  ..\User\why\abc.txt
const file2path = path.resolve(basepath, filename);
console.log(file2path);//  D:\Microsoft VS Code web Node\01.Node基础\03.常见的内置模块\User\why\abc.txt
2.fs

fs是File System的缩写,表示文件系统。

(1)fs的API

fs这些API大多数都提供三种操作方式:

  • 方式一:同步操作文件:代码会被阻塞,不会继续执行;
  • 方式二:异步回调函数操作文件:代码不会被阻塞,需要传入回调函数,当获取到结果时,回调函数被执行;
  • 方式三:异步Promise操作文件:代码不会被阻塞,通过 fs.promises 调用方法操作,会返回一个Promise, 可以通过then、catch进行处理;
const fs = require('fs')

// 1.方式一: 同步读取文件
const state = fs.statSync('../foo.txt');
console.log(state);
console.log("后续代码");

// 2.方式二:异步读取
fs.stat('../foo.txt', (err, state) => {
  if(err) {
    console.log(err);
    return ;
  }
  console.log(state);
})
console.log("后续代码执行");

// 3.方式三:Promise方式
fs.promises.stat('../foo.txt').then(state => {
  console.log(state);
  console.log(state.isDirectory());
}).catch(err => {
  console.log(err);
})
console.log("后续代码");
(2)描述符
  • 在 POSIX 系统上,对于每个进程,内核都维护着一张当前打开着的文件和资源的表格。
  • 每个打开的文件都分配了一个称为文件描述符的简单的数字标识符。
  • 在系统层,所有文件系统操作都使用这些文件描述符来标识和跟踪每个特定的文件。
  • Windows 系统使用了一个虽然不同但概念上类似的机制来跟踪资源。
  • 为了简化用户的工作,Node.js 抽象出操作系统之间的特定差异,并为所有打开的文件分配一个数字型的文件描述 符。
const fs = require('fs');

// 获取文件描述符
fs.open('./abc.txt', (err ,fd) => {
  if(err) {
    console.log(err);
    return ;
  }
  console.log(fd);
})

// 通过文件描述符获取文件信息
fs.fstat(3, (err, info) => {
  console.log(info);
})
(3)文件的读写
  • fs.readFile(path[, options], callback):读取文件的内容;
  • fs.writeFile(file, data[, options], callback):在文件中写入内容;

option参数

  • flag:写入的方式;flag的值:

w 打开文件写入,默认值;

w+ 打开文件进行读写,如果不存在则创建文件;

r+ 打开文件进行读写,如果不存在那么抛出异常;

r 打开文件读取,读取时的默认值;

a 打开要写入的文件,将流放在文件末尾。如果不存在则创建文件;

a+ 打开文件以进行读写,将流放在文件末尾。如果不存在则创建文件

  • encoding:字符的编码; 如果不填写encoding,返回的结果是Buffer;
const fs = require('fs');

// 文件写入
const content = "的房价来说"
fs.writeFile('./abcd.txt', content,{flag: "a"}, err => {
  console.log(err);
});

// 文件读取
fs.readFile("./abc.txt", (err, data) => {
  console.log(data); //<Buffer e7 9a 84 e6 88 bf e4 bb b7 e6 9d a5 e8 af b4>
})
fs.readFile("./abc.txt", {encoding: 'utf-8'}, (err, data) => {
  console.log(data); //的房价来说
})
(4)文件夹的操作

新建文件夹: 使用fs.mkdir()或fs.mkdirSync()创建一个新文件夹

获取文件夹内容

文件夹重命名

const fs= require('fs');
const path = require('path')

// 1.创建文件夹
const dirname = './why';
if(!fs.existsSync(dirname)) {
  fs.mkdir(dirname, err => {
    console.log(err);
  })
}

// 2.读取文件夹中的所有文件
fs.readdir(dirname, (err, files) => {
  console.log(files);
});
const dirname = './why';

function getFiles(dirname) {
  fs.readdir(dirname,{withFileTypes: true}, (err, files) => {
    for (let file of files) {
      if (file.isDirectory()) {
        const filepath = path.resolve(dirname, file.name);
        getFiles(filepath)
      } else {
        console.log(file.name);
      }
    }
  })
}
getFiles(dirname)


// 3.文件夹的重命名
fs.rename('./why', './kobe', err => {
  console.log(err);
})
3.events

六、包管理工具npm

1.简介
  • 包管理工具npm:

    • Node Package Manager,也就是Node包管理器;
    • 但是目前已经不仅仅是Node包管理器了,在前端项目中我们也在使用它来管理依赖的包;
    • 比如express、koa、react、react-dom、axios、babel、webpack等等;
  • npm管理的包可以在哪里查看、搜索呢?

    • https://www.npmjs.com/ :这是我们安装相关的npm包的官网;
  • npm管理的包存放在哪里呢?

    • 我们发布自己的包其实是发布到registry上面的;
    • 当我们安装一个包时其实是从registry上面下载的包;
2.项目配置文件

每一个项目都会有一个对应的配置文件,无论是前端项目还是后端项目,这个配置文件会记录着你项目的名称、版本号、项目描述等;也会记录着你项目所依赖的其他库的信息和依赖库的版本号;这个配置文件在Node环境下面(无论是前端还是后端)就是package.json

cli4脚手架的项目配置项

在这里插入图片描述

3.配置文件常见属性
(1)必须填写的属性
  • name是项目的名称;
  • version是当前项目的版本号;
  • description是描述信息,很多时候是作为项目的基本描述;
  • author是作者相关信息(发布时用到);
  • license是开源协议(发布时用到)
(2)private属性
  • private属性记录当前的项目是否是私有的;
  • 当值为true时,npm是不能发布它的,这是防止私有项目或模块发布出去的方式;
(3)main属性
  • 设置程序的入口。
  • 疑惑,webpack不是会自动找到程序的入口吗?
    • 这个入口和webpack打包的入口并不冲突;
    • 它是在你发布一个模块的时候会用到的;
    • 比如axios文件夹下也有index.js和package.json文件,main属性对应的便是axios文件夹下的index.js文件
(4)scripts属性
  • scripts属性用于配置一些脚本命令,以键值对的形式存在;
  • 配置后我们可以通过 npm run 命令的key来执行这个命令;
  • npm start和npm run start的区别是什么?
    • 它们是等价的;
    • 对于常用的 start、 test、stop、restart可以省略掉run直接通过 npm start等方式运行;
  • 如配置一个**“start”: “node ./sandbox/server.js”**,只需要在命令行输入npm run start便可执行start对应的命令。
(5) dependencies属性
  • dependencies属性是指定无论开发环境还是生成环境都需要依赖的包;
  • 通常是我们项目实际开发用到的一些库模块;
  • 与之对应的是devDependencies;
(6) devDependencies属性
  • 一些包在生成环境是不需要的,比如webpack、babel等;
  • 这个时候我们会通过 npm install webpack --save-dev,将它安装到devDependencies属性中;
(7) engines属性
  • engines属性用于指定Node和NPM的版本号;
  • 在安装的过程中,会先检查对应的引擎版本,如果不符合就会报错;
  • 事实上也可以指定所在的操作系统 “os” : [ “darwin”, “linux” ],只是很少用到;
(8) browserslist属性
  • 用于配置打包后的JavaScript浏览器的兼容情况,参考;
  • 否则我们需要手动的添加polyfills来让支持某些语法;
  • 也就是说它是为webpack等打包工具服务的一个属性(这里不是详细讲解webpack等工具的工作原理,所以 不再给出详情);
4.版本管理问题

安装的依赖版本出现:^2.0.3或~2.0.3,这是什么意思呢?

  • npm的包通常需要遵从semver版本规范;

  • semver版本规范是X.Y.Z:

    • X主版本号(major):当你做了不兼容的 API 修改(可能不兼容之前的版本);
    • Y次版本号(minor):当你做了向下兼容的功能性新增(新功能增加,但是兼容之前的版本);
    • Z修订号(patch):当你做了向下兼容的问题修正(没有新功能,修复了之前版本的bug);
  • ^和~的区别:

    • ^x.y.z:表示x是保持不变的,y和z永远安装最新的版本;
    • ~x.y.z:表示x和y保持不变的,z永远安装最新的版本;
5.npm install 命令
  • 安装npm包分两种情况:
    • 全局安装(global install): npm install axios -g
    • 项目(局部)安装(local install): **npm install axios **

:使用npm全局安装的包都是一些工具包:yarn、webpack等;并不是类似于 axios、express、koa等库文件;所以全局安装了之后并不能让我们在所有的项目中使用 axios等库。

  • 局部安装分为开发时依赖和生产时依赖:
# 安装开发和生产依赖
npm install axios
npm i axios

# 开发依赖
npm install webpack --save-dev
npm install webpack -D
npm i webpack –D

# 根据package.json中的依赖包
npm install
6.项目安装

目安装会在当前目录下生产一个 node_modules 文件夹

7.npm install 原理

在这里插入图片描述

首先 npm install会检测是有package-lock.json文件。然后

  • 没有lock文件

    • 分析依赖关系,这是因为我们可能包会依赖其他的包,并且多个包之间会产生相同依赖的情况;
    • 从registry仓库中下载压缩包(如果我们设置了镜像,那么会从镜像服务器下载压缩包);
    • 获取到压缩包后会对压缩包进行缓存(从npm5开始有的);
    • 将压缩包解压到项目的node_modules文件夹中(前面我们讲过,require的查找顺序会在该包下面查找)
  • 有lock文件

    • 检测lock中包的版本是否和package.json中一致(会按照semver版本规范检测);
      • 不一致,那么会重新构建依赖关系,直接会走顶层的流程;
    • 一致的情况下,会去优先查找缓存
      • 没有找到,会从registry仓库下载,直接走顶层流程;
    • 查找到,会获取缓存中的压缩文件,并且将压缩文件解压到node_modules文件夹中;
8.package-lock.json文件

在这里插入图片描述

  • package-lock.json文件解析:
  • name:项目的名称;
  • version:项目的版本;
  • lockfileVersion:lock文件的版本;
  • requires:使用requires来跟着模块的依赖关系;
  • dependencies:项目的依赖
    • 当前项目依赖axios,但是axios依赖follow-redireacts;
    • axios中的属性如下:
      • version表示实际安装的axios的版本;
      • resolved用来记录下载的地址,registry仓库 中的位置;
      • requires记录当前模块的依赖;
      • integrity用来从缓存中获取索引,再通过索引 去获取压缩包文件;
9.npm其他命令
  • 卸载某个依赖包:
    • npm uninstall package
    • npm uninstall package --save-dev
    • npm uninstall package -D
  • 强制重新build
    • npm rebuild
  • 清除缓存
    • npm cache clean
  • npm的命令其实是非常多的: https://docs.npmjs.com/cli-documentation/cli 更多的命令,可以根据需要查阅官方文档
10.其他包管理工具
(1)Yarn工具
  • yarn是由Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具;
  • yarn 是为了弥补 npm 的一些缺陷而出现的;
  • 早期的npm存在很多的缺陷,比如安装依赖速度很慢、版本依赖混乱等等一系列的问题;
  • 虽然从npm5版本开始,进行了很多的升级和改进,但是依然很多人喜欢使用yarn;
(2)cnpm工具
  • 由于一些特殊的原因,某些情况下我们没办法很好的从 https://registry.npmjs.org下载下来一些需要的包。
  • 查看npm镜像:npm config get registry # npm config get registry
  • 我们可以直接设置npm的镜像:npm config set registry https://registry.npm.taobao.org
  • 且将cnpm设置为淘宝的镜像: npm config get registry # npm config get registry npm config set registry https://registry.npm.taobao.org npm install -g cnpm --registry=https://registry.npm.taobao.org cnpm config get registry # https://r.npm.taobao.org/
(3)npx工具
  • npx是npm5.2之后自带的一个命令。 npx的作用非常多,但是比较常见的是使用它来调用项目中的某个模块的指令。
  • 解决局部命令执行。

七、Buffer的使用

Node为了可以方便开发者完成更多功能,提供给了我们一个类Buffer,并且它是全局的。

Buffer中存储的是二进制数据,那么到底是如何存储呢?

  • 我们可以将Buffer看成是一个存储二进制的数组;
  • 这个数组中的每一项,可以保存8位二进制: 00000000
  • Buffer相当于是一个字节的数组,数组中的每一项对应一个字节的大小.

八、事件循环

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值