【青训营】- Node.js简单了解

487 阅读5分钟

Node.js

1.Node.js简介

Node.js简介

不是一门语言,而是一个JavaScript运行环境,类似于JavaJVM

Node.js上一个基于Google V8 引擎的、垮平台的JavaScript运行环境

官网:Node.js (nodejs.org)

版本:有奇数版本和偶数版本,偶数版本是LTS长期维护版本

安装与运行

index.js

const { readFile } = require('fs');

readFile('./package.json', { encoding: 'utf-8' }, (err, data) => {
    if (err) {
        throw err;
    }
    console.log(data);
})

运行

node index.js

版本管理

使用nvm管理Node.js

Mac&&Linux版本

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash

Windows版本coreybutler/nvm-windows: A node.js version management utility for Windows. Ironically written in Go. (github.com)

//	安装指定版本的Node
nvm install 16.6.2
//	列出系统中已经安装的版本
nvm ls

//	使用指定版本的Node
nvm use 16.6.2

//	卸载指定版本
nvm uninstall 16.6.2

特点

异步I/O

Node.js执行I/O操作时,会在响应返回并恢复操作,而不是阻塞线程并浪费CPU循环等待

代码编写顺序与执行顺序无关

const { readFile } = require('fs');

readFile('./package.json', { encoding: 'utf-8' }, (err, data) => {
    if (err) {
        throw err;
    }
    console.log(data);
});
console.log(123456);

未命名绘图

单线程

Node.js保持了JavaScript在浏览器中单线程的特点

优点

不用处处在意状态同步的问题,不会发送死锁

没有线程上下文切换带来的性能开销

缺点

无法利用多核CPU

错误会引起整个应用退出,健壮性不足

大量计算导致CPU无法继续执行

以浏览器为例,浏览器是多进程,JS引擎是单线程

浏览器进程一般包括浏览器进程、GPU进程、渲染器进程、插件进程。

  • GUI渲染进程
  • JS引擎进程+V8
  • 事件触发线程
  • 定时器触发线程
  • 异步请求线程

垮平台

兼容Windows*nix平台,主要得益于在操作系统与Node.js上层模块之间构建了一层平台架构。

应用场景

Node.js适用于I/O密集型的应用

  • Web应用:Express/Koa
  • 前端构建:Webpack
  • GUI客户端软件:VScode/网易云音乐
  • 其他:实时通讯、爬虫、CLI等

2.模块化机制

模块化简介

1.什么是模块化?

根据功能或业务将一个大程序拆分成互相依赖的小文件,再用简单的方式拼接起来

2.为什么模块化?无模块化问题

所有script标签必须保证顺序正确,否则会依赖报错

全局变量存在命名冲突,占用内存无法被回收

IIFE/namespace会导致代码可读性低等诸多问题

CommonJS规范

Node.js支持CommonJS模块规范,采用同步机制加载模块

exports===module.exports,在内存中指向同一块引用

加载方式

  1. 加载内置模块require('fs')

  2. 加载相对|绝对路径的文件模块

    require('c:\abc\file.js')
    require('.\file.js')
    
  3. 加载npm包require('lodash')

npm包查找原则:require('lodash'

  1. 当前目录node_modules
  2. 如果没有,父级目录的node_modules
  3. 如果没有,沿着路径向上递归,直到根目录下node_modules
  4. 找到之后会加载package.jsonmain指向的文件,如果没有package.json文件则依次查找index.jsindex.jsonindex.node

require.cache中缓存着加载过的模块,缓存的原因:同步加载

  1. 文件模块查找耗时时,如果每次require都需要重新遍历查找,性能会比较差;
  2. 在实际开发中,模块可能包含副作用代码
  • AMD 是 RequireJS 在推广过程中规范化产出,异步加载,推崇依赖前置;
  • CMD 是 SeaJS 在推广过程中规范化产出,异步加载,推崇就近依赖;
  • UMD (Universal Module Definition) 规范,兼容 AMD 和 CommonJS 模式
  • ES Modules (ESM),语言层面的模块化规范,与环境无关,可借助 babel 编译

ESM是在ES6语言层面提出的一种模块化标准

ESM中主要有importexport两个关键词,不能console打印两个关键词

m1.mjs文件

<script type="module" src="m1.mjs"></script>

3.包管理机制

npm介绍

包一般包括index.jspackage.json

NPMNode.js中的包管理器,提供了安装、删除等其他命令来管理包

package.json文件

  • name 包名称
  • version 版本号
  • main 入口文件
  • scripts 执行脚本
  • dependencies 线上依赖
  • devDependencies 开发依赖
  • repository 代码托管地址

更多配置

package.json | npm Docs (npmjs.com)

  • dependencies 业务依赖,应用发布后正常执行所需要的包
  • devDependencies 开发依赖,只用于开发环境
  • peerDependencies 同等依赖,比如一个 webpack 插件依赖特定版本的 webpack
  • bundledDependencies 打包依赖(npm run pack),必须已经在 devDep 或者 dep声明过
  • optionalDependencies 可选依赖

私有NPM

镜像公司内部私有npm

镜像设置

npm config set registry=https://xxxxxxx
  • 并行安装
  • 扁平管理
  • 锁文件
  • 缓存优化

常用命令

npm init
npm config
npm run [cmd]
npm install [pkg]
npm uninstall [pkg]
npm update [pkg]
npm info [pkg]
npm publish

4.异步编程

callback

promise

promise是一个具有四个状态的有限状态机,其中有三个核心状态

  • pending挂起
  • fulfilled完成
  • rejected拒绝

以及一个未开始状态

async

await函数使用try catch捕获异常

event

发布订阅模式Node.js内置events模块

HTTP serve on('request')事件监听

5.Web应用开发

http模块

const http = require('http');

http.createServer((req, res) => {
    res.end('hello');
}).listen(3000, () => {
    console.log('启动成功');
});

Koa介绍

基于Node.js平台的下一代Web开发框架

const app = new Koa();

app.use(async ctx => {
    ctx.body = 'hello';
});
app.listen(3000, () => {
    console.log('启动成功');
});

执行过程

  • 服务启动
    • 实例化 application
    • 注册中间件
    • 创建服务、监听端口
  • 接受/处理请求
    • 获取请求 req、res 对象
    • req -> request、res -> response 封装
    • request & response -> context
    • 执行中间件
    • 输出设置到 ctx.body 上的内容

中间件

Koa应用程序是一个包含一组中间件函数的对象,它是按照洋葱模型组织和执行的

6.开发调试

断点调试

node --inspect=0.0.0.0:9229 bootstrap.js

ndb工具

npm install ndb -g

ndb node bootstrap.js

使用vscode调试

线上调试

  • SDK上报
  • 写入到文件

7.线上部署

Node.js虽然是单线程模型,但是其基于事件驱动、异步非阻塞模式,可应用于高并发场景,同时避免了线程创建、线程之间上下文切换所产生的资源开销。

利用多核CPU

Node.js提供了cluster/child_process模块

进程管理工具
  • 多进程
  • 自动重启
  • 负载均衡
  • 日志查看
  • 性能监控

nodeman

pm2