运行时

Node.js

HTTP、文件、异步、Crypto 与进程脚本常用片段。 — 共 16 条

共 16 条代码片段

A. 基础

创建 HTTP 服务

import http from "node:http";

const server = http.createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "application/json" });
  res.end(JSON.stringify({ ok: true }));
});

server.listen(3000, () => {
  console.log("http://localhost:3000");
});

读取环境变量

const port = Number(process.env.PORT ?? 3000);
const nodeEnv = process.env.NODE_ENV ?? "development";

路径拼接

import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const file = path.join(__dirname, "data", "config.json");

读写文件

import fs from "node:fs/promises";

const content = await fs.readFile("./data.txt", "utf8");
await fs.writeFile("./out.txt", content, "utf8");
await fs.appendFile("./log.txt", "hello\n", "utf8");

读写 JSON 文件

import fs from "node:fs/promises";

const data = JSON.parse(await fs.readFile("./config.json", "utf8"));
await fs.writeFile("./config.json", JSON.stringify(data, null, 2), "utf8");

B. 异步与工具

并发请求

const [a, b] = await Promise.all([fetchUser(1), fetchUser(2)]);

延迟执行

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
await sleep(1000);

失败重试

async function retry(fn, times = 3) {
  let lastError;
  for (let i = 0; i < times; i++) {
    try {
      return await fn();
    } catch (err) {
      lastError = err;
    }
  }
  throw lastError;
}

流式拷贝文件

import { createReadStream, createWriteStream } from "node:fs";
import { pipeline } from "node:stream/promises";

await pipeline(
  createReadStream("./in.txt"),
  createWriteStream("./out.txt")
);

C. Crypto / 安全

哈希

import crypto from "node:crypto";

const hash = crypto.createHash("sha256").update("hello").digest("hex");

生成随机 Token

import crypto from "node:crypto";

const token = crypto.randomBytes(32).toString("hex");

HMAC 签名

import crypto from "node:crypto";

const sign = crypto
  .createHmac("sha256", "secret")
  .update("payload")
  .digest("hex");

D. 进程与脚本

执行命令

import { exec } from "node:child_process";
import { promisify } from "node:util";

const execAsync = promisify(exec);
const { stdout } = await execAsync("node -v");
console.log(stdout.trim());

读取命令行参数

// node script.js --name=vic
const args = process.argv.slice(2);
console.log(args);

优雅退出

process.on("SIGINT", () => {
  console.log("shutting down...");
  process.exit(0);
});

process.on("unhandledRejection", (err) => {
  console.error(err);
  process.exit(1);
});

package.json scripts

{
  "scripts": {
    "dev": "node --watch src/index.js",
    "start": "node src/index.js",
    "test": "node --test"
  }
}