此次nodejs教程应该都会采用Typescript语法,Typescript是JavaScript的超集,增加了类型判断,用过就回不去js了
以及,全篇能使用的地方都会优先import(ESM),require(CommonJS)少用别用
安装
直接安装Nodejs
已不再推荐,建议是卸了再安装版本管理器,用docker都好,别直装
Node.js中文网官网下载地址:https://nodejs.cn/download/ ,直接下载就完事了
官网网址:https://nodejs.org/en/download/package-manager,官网推荐用node版本管理器下载
NVM:node版本管理器
我推荐用NVM是因为我只用过NVM
有些老项目(尤其是工作时),需要更古老的nodejs/npm环境,然而你可能还需要同时拥有一些新东西,直接安装在全局环境变量的nodejs肯定不能同时满足这种需求,所以你需要一个管理器。所以,为了安装这个管理器,你需要先把电脑上的nodejs卸载了,如果是Windows系统,控制面板->添加或删除程序->卸载Nodejs即可,linux不知道,自己解决。至于为什么linux不知道,因为linux上我会直接用docker安装nodejs虚拟环境,主环境里都没有node这个东西,再加上现在我写个人项目用deno而不是node了。
安装
如果是linux,有安装脚本:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash
# 或者你使用wget
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash
# 然后刷新终端环境
source ~/.bashrc镜像配置
阿里云镜像
nvm npm_mirror https://npmmirror.com/mirrors/npm/
nvm node_mirror https://npmmirror.com/mirrors/node/使用
具体使用方式:
# 检查版本
nvm --version
# 列出可安装的所有版本
nvm ls available
# 安装特定版本
nvm install 14.17.0
# 将系统环境切换到指定版本
nvm use 14.17.0
# 列出已安装以及正在使用的版本
nvm ls这里再提一嘴LTS和Current的区别:
LTS(Long Term Support)指长期支持版本
Current实验性功能的新开发版本
没什么特殊需求新项目无脑最新LTS就可以了
Deno 新一代Typescript运行时
在学过ts后,你应该不会很再想js了,这个时候,你发现你在写nodejs小脚本的时候为了支持ts,你又要装tsc、ts-node,超级麻烦,所以这里有一个nodejs原作者写的新一代deno作为ts运行时,现已加入rust重构前端工具链的经典套餐
安装
linux:
curl -fsSL https://deno.land/install.sh | shwindows:
iwr https://deno.land/install.ps1 -useb | iex
choco install deno
scoop install denomac
brew install denocargo源码构建
cargo install deno --locked执行
# as node
deno run -A ./src/main.ts
# as nodemon
deno run -A --watch ./src/main.tsNodejs 特有模块
fs 基础文件操作
引入:
const fs = require('fs');
import * as fs from 'node:fs';
import * as fs from 'node:fs/promises'; // 使用基于回调的api至于为什么要使用node:fs而不是fs,是因为要兼容deno,deno在笔记写下的时候还和node+npm生态没有特别好的兼容,但是通过node:xx前缀,我们可以让node模块在两种环境下同时运行
import { readFileSync } from "node:fs";
console.log(readFileSync("deno.json", { encoding: "utf8" }));
import * as fs from 'node:fs';
// fs.readFile(__dirname + path[,options],callback) //文件路径,编码格式,回调函数
fs.readFile('./files/1.txt','utf8', (err,dataStr) => {
if(err) return console.log('读取文件失败' + err.message)
})
// 如果读取成功,则err的值为null;如果读取失败,err的值为 错误对象,dataStr的值变为 undefined
// fs.writeFile(__dirname + path,data[,options],callback) //data是字符串;options可选,默认utf8
fs.writeFile('./files/2.txt','abcd', (err) => {
if(err) return console.log(err)
console.log('文件写入成功!')
})path 路径模块
import * as path from "node:path"
path.join() //将多个路径片段拼接成一个完整的路径字符串
const pathStr = path.join('/a','/b/c','../','d','e') //'../'返回上级文件夹
cosole.log(pathStr) //输出 \a\b\d\e
path.basename(path[,ext]) //用来从路径字符串中,将文件名解析出来
//path<String>表示一个路径的字符串,ext<String>表示文件扩展名,返回<String>表示路径中的最后一部分
path.extname(path) //用于得到拓展名http 网络模块
import * as http from "node:http"
const server = http.createServer()
server.on('request',(req,res) => {
//req是请求对象,包含了与客户端相关的数据和属性,例如
//req.url 是客户端请求的url地址,req.method是客户端的method请求类型
console.log('Someone visit our web server')
//为了防止中文显示乱码问题,需要设置响应头
res.setHeader('Content-Type','text/html; charset=utf-8')
//把内容响应给客户端,并结束这次请求
const url = req.url
let content = '<h1>404 Not found!</h1>'
if(url === '/' || url === '/index.html') content = '<h1>首页</h1>'
else if(url === '/about.html') cotent = '<h1>关于</h1>'
res.end(content)
})
server.listen(80, ()=>{ //运行在80端口可忽略
console.log('http server running at http://127.0.0.1')
})常用npm包 for nodejs
Koa 后端框架
小,轻,优雅,国内火(但谁用nodejs呢),海外不如express(可能是因为Vue和React的脚手架内置了express)
安装
pnpm i koa
pnpm i --save-dev @types/koa使用
import Koa from 'koa';
const app = new Koa();
// 响应
app.use(ctx => {
ctx.body = 'Hello Koa';
});
app.listen(3000);快速启动
安装常用中间件(koa-router, koa-body, @koa/cors)
pnpm i koa
pnpm i koa-body
pnpm i koa-router
pnpm i @koa/cors
pnpm i --save-dev @types/koa
pnpm i --save-dev @types/koa-router
pnpm i --save-dev @types/koa__corsmain.ts
import Koa from 'koa';
import Router from 'koa-router';
import { koaBody } from 'koa-body';
import cors from '@koa/cors';
const app = new Koa();
const router = new Router()
app.use(cors());
app.use(koaBody());
router.get('/', ctx => {
ctx.body = 'Hello Koa'
})
router.post('/test', ctx => {
ctx.body = `Request Body: ${JSON.stringify(ctx.request.body)}`;
})
app.use(router.routes())
app.use(router.allowedMethods())
app.listen(3000);静态资源 koa-static
安装
pnpm install koa-static
pnpm i --save-dev @types/koa-static
pnpm i koa-mount
pnpm i --save-dev @types/koa-mount配置swagger
安装
pnpm i -D swagger-jsdoc koa2-swagger-ui
pnpm i --save-dev @types/swagger-jsdoc./src/swagger.conf.ts
import swaggerJSDoc from "swagger-jsdoc";
const swaggerDefinition = {
info: {
title: "My Swagger",
version: "1.0.0",
description: "My Swagger Description",
},
host: `localhost:3000`, // 指定项目地址,建议在环境参数中配置,然后用 process.env 读取
basePath: "/",
};
const options = {
swaggerDefinition,
apis: ["./src/routes/*.js", "./src/routes/*.ts"],
};
const swaggerSpec = swaggerJSDoc(options);
export default swaggerSpec;main.ts
import Koa from 'koa';
import { koaBody } from 'koa-body';
import cors from '@koa/cors';
import { koaSwagger } from "koa2-swagger-ui";
import router from './routes/index.ts';
import swaggerSpec from "./swagger.conf.ts"; // 注意文件路径
const app = new Koa();
app.use(cors());
app.use(koaBody());
router.get("/swaggerDoc", async (ctx) => { ctx.body = swaggerSpec; });
app.use(
koaSwagger({
routePrefix: "/docs", // 交互界面 url
swaggerOptions: { url: "http://localhost:3000/swaggerDoc" }
})
);
app.use(router.routes())
app.use(router.allowedMethods())
app.listen(3000);防止你不会swagger注释
/**
* @swagger
* definitions:
* Project:
* type: object
* properties:
* id:
* type: string
* description: 项目的唯一标识符
* example: "UUID-1"
* name:
* type: string
* description: 项目名称
* example: "qqbot"
* version:
* type: string
* description: 项目版本号
* example: "0.0.1"
* modity_time:
* type: string
* format: date-time
* description: 项目最后修改时间
* cover:
* type: string
* format: uri
* description: 项目封面图片链接
* example: "https://qzonestyle.gtimg.cn/qzone/qzact/act/external/tiqq/logo.png"
*/
/**
* @swagger
* /home/getProjectList:
* get:
* summary: 获取项目列表
* description: 获取项目列表的详细信息
* tags:
* - Home
* parameters:
* - in: query
* name: class
* type: string
* description: 如果含有参数, 则返回对应分类的项目
* required: false
* responses:
* 200:
* description: 成功返回项目列表
* schema:
* type: array
* items:
* $ref: "#/definitions/Project"
*/
router.get('/getProjectList', async (ctx, next) => {
ctx.response.body = [{
id: "UUID-1",
name: "qqbot",
version: "0.0.1",
modity_time: new Date(),
cover: "https://qzonestyle.gtimg.cn/qzone/qzact/act/external/tiqq/logo.png"
}]
await next();
})