Deno的生态系统:探索Deno库与工具

584 阅读4分钟

Deno 是一个现代的 JavaScript/TypeScript 运行时环境,由 Node.js 的创始人 Ryan Dahl 创建。Deno 设计的目标是更安全、更简洁、更易于使用。Deno 支持 ES 模块系统,并且内置了许多实用的功能,如 TypeScript 支持、标准库、HTTP 服务器等。

Deno 的生态系统包括许多有用的库和工具,这些库和工具可以帮助开发者快速构建高质量的应用程序。

Deno 标准库

Deno 自带了一个强大的标准库,提供了许多常用的工具和功能。

文件操作 Deno 标准库提供了丰富的文件操作方法,如读取、写入、删除等。

示例代码

// 读取文件
const contents = await Deno.readTextFile("example.txt");
console.log(contents);

// 写入文件
await Deno.writeTextFile("output.txt", "Hello, Deno!");

// 删除文件
await Deno.remove("example.txt");

// 列出目录
const entries = await Deno.readDir("path/to/directory");
for await (const entry of entries) {
  console.log(entry.name);
}

HTTP 服务器

Deno 提供了内置的 HTTP 服务器功能,可以轻松创建简单的 Web 服务。

示例代码

import { serve } from "https://deno.land/std@0.147.0/http/server.ts";

serve(async (req) => {
  if (req.method === "GET" && req.url.pathname === "/") {
    return new Response("Hello, Deno!");
  }
  return new Response("Not Found", { status: 404 });
});

加密与安全

Deno 提供了加密相关的功能,如生成随机数、加密解密等。

import { crypto } from "https://deno.land/std@0.147.0/crypto/mod.ts";

// 生成随机数
const randomBytes = await crypto.getRandomValues(new Uint8Array(16));
console.log(randomBytes);

// 加密解密
const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 },
  true,
  ["encrypt", "decrypt"]
);

const plaintext = new TextEncoder().encode("Hello, Deno!");
const ciphertext = await crypto.subtle.encrypt(
  { name: "AES-GCM", iv: new Uint8Array(12) },
  key,
  plaintext
);

const decrypted = await crypto.subtle.decrypt(
  { name: "AES-GCM", iv: new Uint8Array(12) },
  key,
  ciphertext
);
console.log(new TextDecoder().decode(decrypted));
第三方库

除了标准库之外,Deno 社区还提供了许多第三方库,这些库可以帮助开发者解决特定的问题。

ORM (Object-Relational Mapping) Deno 提供了一些 ORM 库,如 better-sqlite3 和 sqlite。

import { Database } from "https://deno.land/x/sqlite@v3.4.0/mod.ts";

const db = new Database(":memory:");

await db.execute(`
  CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL
  );
`);

await db.execute("INSERT INTO users (name) VALUES (?)", ["Alice"]);
await db.execute("INSERT INTO users (name) VALUES (?)", ["Bob"]);

const rows = await db.query("SELECT * FROM users");
for await (const row of rows) {
  console.log(row);
}

WebSocket 服务器 Deno 提供了 WebSocket 服务器库,如 ws。

import { serve } from "https://deno.land/std@0.147.0/http/server.ts";
import { WebSocket } from "https://deno.land/std@0.147.0/websocket/mod.ts";

serve(async (req) => {
  if (req.method === "GET" && req.url.pathname === "/ws") {
    const { conn, r: reader, w: writer } = await WebSocket.accept(req);
    console.log("WebSocket connection established.");

    for await (const msg of reader) {
      console.log("Received:", msg);
      writer.write(msg);
    }

    conn.close();
    return;
  }

  return new Response("Not Found", { status: 404 });
});

GraphQL 服务器 Deno 提供了 GraphQL 服务器库,如 graphql。

import { serve } from "https://deno.land/std@0.147.0/http/server.ts";
import { graphqlHTTP } from "https://esm.sh/graphql-http@0.18.0";
import { makeExecutableSchema } from "https://esm.sh/graphql-tools@8.3.0";

const typeDefs = `
  type Query {
    hello(name: String): String
  }
`;

const resolvers = {
  Query: {
    hello: (_: any, { name }: { name: string }) => `Hello, ${name}!`,
  },
};

const schema = makeExecutableSchema({ typeDefs, resolvers });

serve(async (req) => {
  if (req.method === "GET" || req.method === "POST") {
    return await graphqlHTTP({
      schema,
      graphiql: true,
    })(req);
  }

  return new Response("Not Found", { status: 404 });
});

Deno 工具

除了库之外,Deno 还提供了许多有用的工具,帮助开发者更高效地开发和部署应用程序。

Deno Deploy

Deno Deploy 是一个无服务器平台,允许开发者轻松部署 Deno 应用程序。

创建 Deno Deploy 项目

deno deploy init

编写示例代码

import { serve } from "https://deno.land/std@0.147.0/http/server.ts";

serve(async (req) => {
  if (req.method === "GET" && req.url.pathname === "/") {
    return new Response("Hello, Deno Deploy!");
  }
  return new Response("Not Found", { status: 404 });
});

部署项目

deno deploy --name my-app

查看部署结果

deno deploy info my-app
Deno Lint

Deno Lint 是一个代码质量检查工具,帮助开发者发现代码中的问题。

安装 Deno Lint

deno install -A --unstable --allow-read --allow-write --allow-run --name denolint https://deno.land/x/denolint@v0.15.0/cli.ts

编写示例代码

// main.ts
console.log("Hello, Deno!");

运行 Deno Lint

denolint main.ts
Deno Cache

Deno Cache 是一个缓存工具,帮助开发者缓存编译后的代码,提高开发效率。

示例代码

安装 Deno Cache

deno install -A --unstable --allow-read --allow-write --allow-run --name denocache https://deno.land/x/denocache@v0.2.0/cli.ts

使用 Deno Cache

denocache main.ts

实际案例分析

使用 Deno 标准库创建文件操作工具

假设我们要创建一个简单的文件操作工具,用于读取、写入和删除文件。

项目结构

src/
  - file_operations.ts

file_operations.ts

import { readTextFile, writeTextFile, remove } from "https://deno.land/std@0.147.0/fs/mod.ts";

async function readFile(filePath: string): Promise<string> {
  return await readTextFile(filePath);
}

async function writeFile(filePath: string, content: string): Promise<void> {
  return await writeTextFile(filePath, content);
}

async function deleteFile(filePath: string): Promise<void> {
  return await remove(filePath);
}

// 示例用法
async function main() {
  const filePath = "example.txt";
  const content = "Hello, Deno!";

  await writeFile(filePath, content);
  console.log("File written successfully.");

  const fileContent = await readFile(filePath);
  console.log("File content:", fileContent);

  await deleteFile(filePath);
  console.log("File deleted successfully.");
}

main().catch((err) => {
  console.error(err);
});

创建一个简单的 HTTP 服务器

假设我们要创建一个简单的 HTTP 服务器,用于响应 GET 请求并返回一些数据。

项目结构

src/
  - http_server.ts

http_server.ts

import { serve } from "https://deno.land/std@0.147.0/http/server.ts";

const port = 8000;

serve(async (req) => {
  if (req.method === "GET" && req.url.pathname === "/") {
    return new Response("Hello, Deno HTTP Server!");
  }
  return new Response("Not Found", { status: 404 });
});

console.log(`Server running on http://localhost:${port}`);

运行 HTTP 服务器

deno run --allow-net http_server.ts

使用 Deno 创建 WebSocket 服务器

假设我们要创建一个简单的 WebSocket 服务器,用于接收客户端消息并回传给客户端。

项目结构

src/
  - websocket_server.ts

websocket_server.ts

import { serve } from "https://deno.land/std@0.147.0/http/server.ts";
import { WebSocket } from "https://deno.land/std@0.147.0/websocket/mod.ts";

const port = 8080;

serve(async (req) => {
  if (req.method === "GET" && req.url.pathname === "/ws") {
    const { conn, r: reader, w: writer } = await WebSocket.accept(req);
    console.log("WebSocket connection established.");

    for await (const msg of reader) {
      console.log("Received:", msg);
      writer.write(msg);
    }

    conn.close();
    return;
  }

  return new Response("Not Found", { status: 404 });
});

console.log(`WebSocket server running on ws://localhost:${port}/ws`);

运行 WebSocket 服务器

deno run --allow-net websocket_server.ts

使用 Deno 创建 GraphQL 服务器

假设我们要创建一个简单的 GraphQL 服务器,用于处理 GraphQL 查询。

项目结构

src/
  - graphql_server.ts

graphql_server.ts

import { serve } from "https://deno.land/std@0.147.0/http/server.ts";
import { graphqlHTTP } from "https://esm.sh/graphql-http@0.18.0";
import { makeExecutableSchema } from "https://esm.sh/graphql-tools@8.3.0";

const typeDefs = `
  type Query {
    hello(name: String): String
  }
`;

const resolvers = {
  Query: {
    hello: (_: any, { name }: { name: string }) => `Hello, ${name}!`,
  },
};

const schema = makeExecutableSchema({ typeDefs, resolvers });

serve(async (req) => {
  if (req.method === "GET" || req.method === "POST") {
    return await graphqlHTTP({
      schema,
      graphiql: true,
    })(req);
  }

  return new Response("Not Found", { status: 404 });
});

console.log("GraphQL server running on http://localhost:4000");

运行 GraphQL 服务器

deno run --allow-net graphql_server.ts

使用 Deno 创建 RESTful API 服务器

假设我们要创建一个简单的 RESTful API 服务器,用于处理 CRUD 操作。

项目结构

src/
  - rest_api_server.ts

rest_api_server.ts

import { serve } from "https://deno.land/std@0.147.0/http/server.ts";
import { parse } from "https://deno.land/std@0.147.0/querystring/mod.ts";

interface User {
  id: number;
  name: string;
}

let users: User[] = [];

const port = 3000;

serve(async (req) => {
  if (req.method === "GET" && req.url.pathname === "/users") {
    return new Response(JSON.stringify(users), { headers: { "Content-Type": "application/json" } });
  }

  if (req.method === "POST" && req.url.pathname === "/users") {
    const body = await req.text();
    const user = JSON.parse(body);
    user.id = users.length + 1;
    users.push(user);
    return new Response(JSON.stringify(user), { headers: { "Content-Type": "application/json" } });
  }

  if (req.method === "PUT" && req.url.pathname.startsWith("/users/")) {
    const id = parseInt(req.url.pathname.split("/")[2]);
    const body = await req.text();
    const updatedUser = JSON.parse(body);

    const index = users.findIndex((u) => u.id === id);
    if (index !== -1) {
      users[index] = { ...users[index], ...updatedUser };
      return new Response(JSON.stringify(users[index]), { headers: { "Content-Type": "application/json" } });
    }

    return new Response("User not found", { status: 404 });
  }

  if (req.method === "DELETE" && req.url.pathname.startsWith("/users/")) {
    const id = parseInt(req.url.pathname.split("/")[2]);
    const index = users.findIndex((u) => u.id === id);
    if (index !== -1) {
      users.splice(index, 1);
      return new Response("User deleted", { status: 200 });
    }

    return new Response("User not found", { status: 404 });
  }

  return new Response("Not Found", { status: 404 });
});

console.log(`RESTful API server running on http://localhost:${port}`);

运行 RESTful API 服务器

deno run --allow-net rest_api_server.ts

使用 Deno 创建数据库操作工具

假设我们要创建一个简单的数据库操作工具,用于连接 SQLite 数据库并执行 CRUD 操作。

项目结构

src/
  - database_operations.ts

database_operations.ts

import { Database } from "https://deno.land/x/sqlite@v3.4.0/mod.ts";

const db = new Database(":memory:");

await db.execute(`
  CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL
  );
`);

async function createUser(name: string): Promise<void> {
  await db.execute("INSERT INTO users (name) VALUES (?)", [name]);
}

async function getUserById(id: number): Promise<any> {
  const result = await db.query("SELECT * FROM users WHERE id = ?", [id]);
  for await (const row of result) {
    return row;
  }
  return null;
}

async function updateUser(id: number, name: string): Promise<void> {
  await db.execute("UPDATE users SET name = ? WHERE id = ?", [name, id]);
}

async function deleteUser(id: number): Promise<void> {
  await db.execute("DELETE FROM users WHERE id = ?", [id]);
}

// 示例用法
async function main() {
  await createUser("Alice");
  await createUser("Bob");

  const user = await getUserById(1);
  console.log("User:", user);

  await updateUser(1, "Charlie");
  const updatedUser = await getUserById(1);
  console.log("Updated User:", updatedUser);

  await deleteUser(2);
  const remainingUsers = await db.query("SELECT * FROM users");
  for await (const row of remainingUsers) {
    console.log("Remaining User:", row);
  }
}

main().catch((err) => {
  console.error(err);
});