node(nodemon工具)
1.什么是node.js
Node.js是一个基于Chrome V8 JS引擎构建的开源、跨平台JS运行环境。允许开发者在服务器端运行JS代码,从而实现前后端统一的开发语言。
Node不是编程语言,是一个JS运行时环境。JS是脚本语言,脚本语言都需要一个解析器才能运行,浏览器是HTML中JS的解析器,Node是需要独立运行JS的解析器。同时Node还提供了可以对文件系统、网络等进行操作的API,Node的出现使JS能够用于服务端编程。
脚本语言:不需要编译成机器码,由解释器逐行读取并直接执行的编程语言,如JavaScript、Python、PHP、Shell
编译型语言:运行前先用编译器转成机器码(二进制文件如
.exe、.dll)如C 语言、C++、Go、RustJava比较特殊,属于半编译半解释,先编译成字节码(.class)的中间文件,再由Java虚拟机JVM解释执行,不是纯粹的编译型语言,也不是脚本语言,牺牲了一点运行速度,换来了跨平台能力。
1.1.node的特点
单线程与事件驱动:Node.js的主程序是单线程的,不像Java/PHP那样为每个请求创建一个新线程。node采用事件循环Event Loop机制,通过监听事件来执行代码。单线程极其省内存,不需要创建成千上万个线程,事件驱动使Node.js 极其高效,通过“不傻等、只监听”的机制,让一个人也能干成百上千个人的活。这两个特性使Node适合做高并发、I/O 密集型的任务(同时处理几万个用户的登录请求、同时转发几万个聊天消息)。但让它去算复杂的计算(CPU 密集型),那个唯一的线程占用卡死
非阻塞 I/O:当执行数据库查询、文件读写或网络请求等耗时操作时,Node不会阻塞,而是把这些任务交给底层的C++线程池,自己立刻去处理下一个请求。等耗时任务完成后,通过回调函数通知主线程。
全栈 JavaScript:前后端使用同一种语言JavaScript,降低了团队的学习和沟通成本
强大的包管理生态:Node自带 npm,这是全球最大、最活跃的开源代码库。
跨平台: Windows、macOS、 Linux6.
高性能的V8引擎:Node.js底层使用了Google开源的V8引擎,该引擎使用 C++ 编写,能将 JS代码直接编译为机器码执行,虽然是脚本语言,但得益于V8的即时编译技术,其执行速度远超传统的解释型语言
Node.js在高并发、微服务、实时通信和前端工程化领域所向披靡,但不适合CPU密集型任务,因为node是单线程,如果执行复杂的数学计算、视频转码等耗时操作,会直接卡死整个事件循环,导致所有其他请求都无法响应。
1.2.node版本
Node通常每年两个主版本,在4月Current版本,10月LTS版本:
Current版:从发布6个月内处于Current状态,然后转为LTS版本。
LTS版本(偶数通常是LTS):从转为LTS版本开始,有18个月的活跃支持期,随后进入12个月的维护支持期。
Maintenance(维护版):维护版是已经过了活跃支持期的LTS版本,主要接收安全更新和关键修复。
nvm是Node版本管理工具,允许在同一系统安装和切换不同版本的Node
nvm安装:开始 下载nvm - nvm中文官网
安装最新版:nvm install node
安装特定版本:nvm install 14.17.0
切换到特定版本(仅当前终端生效):nvm use 14.17.0
设置默认版本(当前终端未生效,但新打开终端生效):nvm alias default 14.17.0
1.3.node模块化
Node基于Commonjs模块化开发的规范,它定义一个JS文件就称是一个模块
导出: module.exports = {num: num}、exports.键 = 值
导入: require('./b.js') .js 后缀可以省略不写
对比ES6模块化的导入导出:export导出 / import导入
3.npm
npm是Node.js的包管理工具:用于安装、管理和共享JS库和应用程序
可使用npm来安装和管理项目依赖的第三方包,管理包的版本,发布和共享自己的包,npm可以运行自定义脚本,帮助开发者自动化各种任务,安装Node时,npm也会被安装在系统中
npm是Node.js生态系统的重要组成部分,提供了庞大的开源模块库,帮助开发者快速构建和扩展应用。npm库包含了数百万个包,涵盖了各种功能和工具,极大地丰富了Node的开发能力。npm通过
package.json文件管理项目的依赖关系,定义项目需要的包及其版本。列出所有已安装的Node.js版本:nvm ls
卸载指定版本:nvm uninstall 14.17.0
4.nodemon
node a.js :以 node 这个 "软件" 来运行 该 js 文件
nodemon是专门用来执行js文件的工具,依赖 node 环境运行,当文件发生变化的时自动重启
npm install --global nodemon // 下载
nodemon --version // 检测
npm uninstall --global nodemon // 卸载
nodemon 文件名称 // 执行js文件
5.package.json
package.json是Node.js 和现代前端项目中不可或缺的核心配置文件1. 项目基础信息(元数据),帮助快速了解项目,也是将项目作为npm包发布时的必填项
name:项目名称(发布到 npm 的必填项,需符合命名规范,如全小写、无空格)。
version:项目版本号(遵循语义化版本规范主.次.修,如1.0.0,发布必填)。
description:项目的一句话描述,帮助他人快速了解项目用途。
author:项目作者信息(可以是字符串或包含 name/email/url 的对象)。
license:开源许可证(如MIT、ISC),声明项目的使用和分发权限。
private:设为true时,npm 会拒绝发布该项目,常用于防止内部项目被意外发布。2. 依赖管理(核心)
dependencies:生产环境依赖。项目运行所必需的包(如 Vue、React、Express),部署到服务器时也必须安装。
devDependencies:开发环境依赖。仅在本地开发、构建、测试时使用的包(如 Webpack、Vite、ESLint),生产环境不需要。
peerDependencies:对等依赖。声明你的包期望宿主环境(或使用者项目)中已经安装的依赖及版本(常见于 UI 组件库或插件,如声明依赖 React)。
optionalDependencies:可选依赖。如果这些包安装失败,不会导致整个npm install过程报错中断。3. 定义自动化脚本与入口配置
type:决定node.js去和解析和加载该项目下的js文件的全局开关,默认是commonjs,表示将所有。js文件视为cjs模块,必须使用require语法;module表示将项目中.js文件视为ESM模块,必须使用import语法,是前端应用的常规配置,无论type如何配置,遇到.mjs永远被视为ESM,.cjs永远被视为CJS
scripts:命令脚本字典。定义可通过npm run <脚本名>执行的命令(如dev、build、test)。
main:CommonJS模块的入口文件(如index.js),Node.js 默认加载此文件。
module:ES Modules模块的入口文件。现代打包工具(如 Webpack/Vite)会优先读取此字段,支持 Tree-shaking。
bin:声明可执行文件。当你的包是一个 CLI 工具时,通过此字段将脚本映射为全局命令
files:白名单数组。指定发布到 npm 时需要包含的文件或目录,避免将源码或测试文件打包发布。4. 工程化与工具配置
engines:声明项目运行所需的 Node或npm版本范围,防止因环境版本过低导致报错
browserslist:声明目标浏览器范围,供 Babel、PostCSS、Autoprefixer 等工具决定代码的降级和兼容处理策略。其他工具配置:如
eslintConfig、prettier、babel等,很多工具支持直接在package.json中配置,从而减少项目根目录下的配置文件数量。dependencies和devDependencies的区别:一个是“运行时依赖”,一个是“开发时依赖”外,在打包部署生产环境时,通常只会安装
dependencies(npm install --production),devDependencies会被忽略,以此来减小生产环境的包体积
7.常用终端命令
- cd :切换到指定目录下(不可切换盘符,tab按键可以快速切换目录,补齐目录名)
- cd.. :回到上一级目录
- 盘符: 切换盘符
- dir :当前目录下有哪些文件或文件夹
- md 文件名:创建文件夹
- rmdir 文件夹名:删除文件夹
- cls、clear:清屏
- ipconfig: 查看电脑ip地址信息
- systeminfo:查看操作系统信息
- pwd 显示当前所在目录路径
- ls() 列出当前目录中的所有文件
- touch 新建一个文件 后边直接跟文件名字
- rm 删除一个文件 后边直接跟名字
- mkdir 新建一个目录(文件夹)
- rm-r 删除一个文件夹爱 rm-r src 删除目录
- rm - rf / 删除电脑中全部文件!! 禁用
- mv 移动文件
- reset 清屏 初始化终端
- clear 清屏
- history 查看命令历史
- help 帮助
- exit 退出
- mkdir 创建新目录
- mkdir -p /path/to/your/directory 创建多级目录结构,即使中间的目录不存在
8.内置模块
8.1.fs文件操作:readFile、writeFile
file system对文件和文件夹的操作处理:const fs = require('fs') 引入fs模块
fs.readFile(文件路径, 'utf8’, (err,data) => {}) 异步读取文件,格式默认buffer, 常用utf-8
fs.readFileSync(文件路径, 格式):同步读取文件,返回文件内容
fs.writeFile(文件路径,写入的内容,err => {})异步写入内容,文件存在会覆盖内容,文件不存在会创建一个新文件
fs.writeFileSync(文件路径,写入内容):同步写入文件内容
fs.existsSync(path) // 检查文件是否存在 返回true/false,(async为异步)
// 获取文件信息(异步)
fs.stat(文件,(err,stats) => {
stats.isDirectory() // 是否是目录(文件夹)
stats.isFile() // 是否为文件
stats.size // 文件大小(以字节为单位)
})
fs.unlink(文件路径,err => {}) // 删除文件(异步)
8.2.path文件路径
const path = require('path') :引入path模块
path.join('/a', 'b', 'c'),返回值: 组装好的是相对路径信息:/a/b/c
path.resolve("a", "../b", "c"), 返回值是组装的绝对路径
__filename:全局变量,当前正在执行的脚本的包含路径的文件名
__dirname:全局变量,当前执行脚本所在的目录路径
不同的系统中路径的/不同,有时是\
path.basename('c:/a/b/c/d.html') // 获取文件名称: d.html
path.dirname('c:/a/b/c/d.html') // 获取目录名:c:/a/b/c
path.extname('c:/a/b/c/d.html') // 获取路径中文件扩展名(后缀): .html
拼装文件绝对路径:path.resolve(__dirname, 'family.db');
8.3.hppt
const http = require("http");
// 创建web服务实例
const server = http.createServer();
// 监听request请求
server.on("request", (req, res) => {
if (req.url === "/") {
res.end("hello world");
}
});
// 启动服务
server.listen(8080, () => {console.log("server is running at http://127.0.0.1:8080")});
request: 接受客户端请求对象,它包含了与客户端相关的数据和属性
request.url客户端请求的uri地址
request.method客户端请求的方式
request.headers客户端请求头信息(对象)
post接口获取数据,需要监听req对象的data事件,如果数据量比较大,无法一次性发送完,客户端会把数据切割后分批发送给服务器。每次触发data事件收到的数据只是一部分,需要拼接获取完整数据
let arr = [];
req.on('data', buffer => {
arr.push(buffer);
});
// 数据传输结束了
req.on('end', () => {
// 拼接接收到的所有数据
let buffer = Buffer.concat(arr);
let post = queryString.parse(buffer.toString())
console.log(post);
});
response:服务器对客户端的响应对象
response.setHeader('content-type', 'text/html;charset=utf-8') //设置响应头中文乱码处理
response.setHeader(状态码,状态描述,{响应头信息}) // 可设置多个响应头信息
response.statusCode = 200(默认200)// 设置状态码
response.end('hello world') // 向客户端发送响应数据,并结束本次请求的处理过程
8.4.url操作网址
const url = require('url')
url.parse(): 解析网址,解析成对象(协议、auth、hostname、port、qyery)
let { query } = url.parse(req.url, true);
8.5.querystring解析查询字符串
用于解析和格式化url查询字符串,URL地址的get形式传参的实用工具
const querystring = require('querystring')
querystring.parse('foo=bar&abc=xyz') // 将query字符串转为对象
querystring.stringify({ foo: 'bar',abc: 'xyz'}) // 对象转为query字符串
querystring.decode('foo=bar&abc=xyz') // 将query字符串转为对象
querystring.encode({ foo: 'bar',abc: 'xyz'}) // 对象转为query字符串
类似JSON.parse()、JSON.stringify()
8.6.os操作系统
operation system:操作系统相关的方法和属性
const os = require('os') // 引入os模块
os.EOL: 根据不同的操作系统生成不同的换行符,window \r\n,linux下面 \n
os.cpus() : cpu相关信息
os.totalmen() : 总内存大小(单位:字节)
os.freemem() : 空余内容大小
os.hostname() : 主机名
os.type() : 系统类型
9.代理
const http = require('http')
// 下载并导入第三方模块http-proxy-middleware
const {createProxyMiddleware} = require 'http-proxy-middliware'
// 推荐方式1,需要在localhost:3000访问可成功代理
let fn = createProxyMiddleware('/api,' {
target: http://www.17989.com/xiaohua/', // 要代理的目标地址
changeOrigin: true, // 改变源头,必加
// 最终的代理目标地址相当于target+自定义地址,比如'/api'
// 是否从最终的目标地址中去掉或替换一部分
pathRewrite: {
'/api': ''
}
})
// 方式2帮助理解,需要在localhost:3000/xiaohua/访问才能成功代理
let fn = createProxyMiddleware('/xiaohua/,' {
target: http://www.17989.com/xiaohua/',
changeOrigin: true,
})
const sever = http.createSever((req, res)=>{
fn(req, res)
})
10.express
基于 Node平台,快速、开放、极简的Web开发框架。是一个 npm 上的第三方包,提供了快速创建 Web 服务器的便捷方法。使用Express开发框架可以非常方便、快速的创建Web网站的服务器或API接口的服务器
npm install express
npm install art-template // 提供模板引擎解析语法,将“模板文件”和“数据”结合,渲染生成最终的 HTML 字符串
npm install express-art-template // Express 框架本身不认识
art-template的语法。这个插件的作用就是告诉 Express当遇到.html或.art后缀的文件时,使用art-template引擎去解析
使用express处理静态资源
const express = require('express')
const fs = require('fs')
// 1. 创建服务
const app = express()
// 前端发送/public/xxx的请求都会去./client 文件夹下查找文件
// 请求/public/css/index.css,自动读取./client/css/index.css文件返回
app.use('/public', express.static('./client'))
app.use('/index.html', function (req, res) {
fs.readFile('./client/index.html', 'utf-8', (err, data) => {
if (err) return console.log(err)
res.end(data)
})
})
app.listen(8080, () => console.log('监听8080 端口成功'))
更多推荐
所有评论(0)