Deno 作为 Node.js 的现代替代品,提供了许多改进和创新,尤其是在安全性、模块系统和开发体验方面。虽然它仍处于发展阶段,但对于寻求简洁、安全和现代化 JavaScript/TypeScript 开发环境的开发者来说,Deno 是一个值得考虑的选择。随着社区的持续发展,Deno 的潜力和影响力有望进一步扩大。
deno run
:执行单个文件。
deno test
:运行测试。
deno fmt
:代码格式化。
deno lint
:代码风格检查。
Deno的配置文件主要以deno.json为主,它可以包含多个配置选项来定制运行时的行为。而环境变量主要影响Deno的全局配置,如日志级别、缓存目录等。
Deno配置文件 (deno.json)
配置文件通常包含以下部分:
{
"permissions": {
"env": true,
"net": ["*"],
"read": ["./data"],
"write": ["./output"]
},
"importMap": {
"imports": {
"lodash": "https://cdn.skypack.dev/lodash@4.17.21",
"my-local-module": "./src/my-local-module.ts"
}
},
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"lib": ["dom", "deno.ns"],
"strict": true
},
"lintRules": {
// ...
},
"watch": true,
"reload": {
"enabled": true,
"include": ["./src"]
}
}
DENO_DIR
: 指定Deno的配置、缓存和下载目录,默认为~/.deno。
DENO_AUTH_TOKEN
: 用于认证的令牌,用于访问私有模块。
DENO_LOGGING_LEVEL
: 控制日志级别,如debug
, info
, warn
, error
。
DENO_CACHE
: 自定义缓存目录。
DENO.land_proxy
: 用于访问deno.land的代理设置。
DENO_NO_COLOR
: 如果设置,将禁用彩色输出。
# Linux/MacOS
export DENO_DIR=/path/to/custom/deno/dir
export DENO_LOGGING_LEVEL=debug
# Windows
set DENO_DIR=%USERPROFILE%\custom\deno\dir
set DENO_LOGGING_LEVEL=debug
请注意,不是所有的配置选项都可以通过环境变量来设置,大部分配置仍然需要通过deno.json
文件来定义。此外,Deno的权限通常是在运行命令时通过命令行标志指定,而不是通过配置文件或环境变量。例如,deno run --allow-read=./data your_script.ts
。
在Deno中创建一个HTTP服务器非常简单,可以使用内置的std/http库。
// server.ts
import { serve } from "https://deno.land/std/http/server.ts";
const s = serve({ port: 8000 });
console.log("Server is running on http://localhost:8000");
for await (const req of s) {
req.respond({ status: 200, body: "Hello, World!\n" });
}
导入serve函数:import { serve } from “https://deno.land/std/http/server.ts”;从Deno的标准库中导入serve函数,这个函数用于创建HTTP服务器。
启动服务器:const s = serve({ port: 8000 });创建并启动服务器,监听8000端口。s是一个可迭代对象,代表服务器接收的每个请求。
打印服务器信息:console.log(“Server is running on http://localhost:8000”);告知用户服务器已经启动,并提供访问地址。
处理请求:for await (const req of s)是一个异步迭代器,它会等待并处理每一个到达的HTTP请求。req是ServerRequest类型的实例,包含了请求的信息。
响应请求:req.respond({ status: 200, body: “Hello, World!\n” });向客户端发送响应。status是HTTP状态码(这里是200,表示成功),body是响应体(这里是字符串"Hello, World!\n")。
运行服务器:在终端中,使用deno run --allow-net server.ts命令运行这个脚本。–allow-net标志是必需的,因为它允许Deno访问网络,这是创建服务器所必需的。
在Deno中获取远程数据,通常使用fetch API
:
// fetch_data.ts
import { assert } from "https://deno.land/std/testing/asserts.ts";
import { json as parseJson } from "https://deno.land/std/io/ioutil.ts";
async function fetchData(url: string) {
const response = await fetch(url);
assert(response.ok, `Failed to fetch data: ${response.statusText}`);
const data = await parseJson(await response.text());
console.log(data);
}
// 示例URL,替换为你想要获取数据的URL
const remoteDataURL = "https://jsonplaceholder.typicode.com/todos/1";
fetchData(remoteDataURL);
代码解析:
// file_operations.ts
import { readTextFile, writeTextFile } from "https://deno.land/std/fs/mod.ts";
// 读取文件
const content = await readTextFile("example.txt");
console.log(content);
// 写入文件
const newContent = "This is new content.";
await writeTextFile("example.txt", newContent);
// http_server.ts
import { serve } from "https://deno.land/std/http/server.ts";
const s = serve({ port: 8000 });
console.log("Server is running on http://localhost:8000");
for await (const req of s) {
req.respond({ status: 200, body: "Hello, World!\n" });
}
Deno使用async/await
语法进行异步操作,这使得代码更加简洁和易于理解。
// async_example.ts
import { delay } from "https://deno.land/std/async/mod.ts";
async function asyncTask() {
console.log("Task started...");
await delay(1000); // 延迟1秒
console.log("Task completed.");
}
asyncTask();
// async_file.ts
import { ensureDir, readTextFile, writeTextFile } from "https://deno.land/std/fs/mod.ts";
import { delay } from "https://deno.land/std/async/mod.ts";
async function asyncFileOps() {
try {
await ensureDir("output"); // 确保目录存在
const content = await readTextFile("input.txt");
console.log("Read content:", content);
const newContent = "New content";
await writeTextFile("output/output.txt", newContent);
console.log("Wrote new content to output file.");
await delay(2000); // 延迟2秒
console.log("Finished async operations.");
} catch (err) {
console.error("An error occurred:", err);
}
}
asyncFileOps();
Deno的模块系统基于ES模块,允许你通过URL导入和导出代码。Deno的标准库提供了许多实用的模块,涵盖了文件系统操作、网络通信、HTTP服务器、JSON处理、加密和更多。
// import_std.ts
import { readTextFile } from "https://deno.land/std/fs/mod.ts";
import { serve } from "https://deno.land/std/http/server.ts";
// 使用readTextFile读取文件
const content = await readTextFile("example.txt");
console.log(content);
// 创建HTTP服务器
const s = serve({ port: 8000 });
console.log("Server is running on http://localhost:8000");
for await (const req of s) {
req.respond({ status: 200, body: "Hello, World!\n" });
}
// my_module.ts
export function add(a: number, b: number): number {
return a + b;
}
// 在其他文件中导入
// import_ts.ts
import { add } from "./my_module.ts";
console.log(add(2, 3)); // 输出 5
// json_example.ts
import { readTextFile } from "https://deno.land/std/fs/mod.ts";
import { json as parseJson } from "https://deno.land/std/json/mod.ts";
const jsonData = await readTextFile("data.json");
const data = parseJson(jsonData);
console.log(data);
// net_example.ts
import { connect } from "https://deno.land/std/net/tcp.ts";
const conn = await connect({ hostname: "localhost", port: 8000 });
conn.write(new TextEncoder().encode("GET / HTTP/1.1\r\nHost: localhost:8000\r\n\r\n"));
const response = new TextDecoder().decode(await Deno.readAll(conn));
console.log(response);
conn.close();
// third_party_module.ts
import { log } from "https://x.nest.land/log@0.1.0/mod.ts";
log.info("This is an info message");
Deno的标准库和第三方模块通常通过HTTPS URL导入,这提供了模块的版本控制和安全。deno.land
是一个模块注册表,类似于npm,但专为Deno设计。x.nest.land
是另一个Deno的模块仓库,提供了一些社区维护的模块。
在Deno中使用WebSocket,可以通过标准库或第三方库来实现。下面的示例将使用第三方库ws,这是一个流行的WebSocket库,适用于Deno和Node.js。
首先,确保安装ws库:
deno install -A -f --unstable --name deno_ws https://deno.land/x/ws@v1.1.0/mod.ts
创建一个WebSocket服务器,监听客户端连接,并向连接的客户端发送消息。
// server.ts
import { Server } from "deno_ws/mod.ts";
const server = new Server({ port: 8080 });
server.on("connection", (socket) => {
console.log("Client connected");
socket.on("message", (message) => {
console.log(`Received message => ${message}`);
socket.send(`You sent -> ${message}`);
});
socket.on("close", () => {
console.log("Client disconnected");
});
});
console.log("WebSocket server is running on ws://localhost:8080");
创建一个WebSocket客户端,连接到上面的服务器,并发送/接收消息。
// client.ts
import { connect } from "deno_ws/mod.ts";
const socket = connect("ws://localhost:8080");
socket.on("open", () => {
console.log("Connected to WebSocket server");
socket.send("Hello, Server!");
});
socket.on("message", (message) => {
console.log(`Received from server: ${message}`);
});
socket.on("close", () => {
console.log("Connection closed");
});
打开两个终端窗口。
在第一个窗口运行服务器:
deno run --allow-net server.ts
在第二个窗口运行客户端:
deno run --allow-net client.ts
Deno使用try/catch
语句进行错误捕获,同时支持异步错误处理。示例:
// error_handling.ts
import { readFile } from "https://deno.land/std/fs/mod.ts";
try {
const data = await readFile("non_existent_file.txt");
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
console.error("File not found:", error);
} else {
throw error; // 未处理的错误继续抛出
}
}
Deno的调试可以通过console.log
、console.error
以及使用debugger
语句配合IDE或浏览器的开发者工具进行。示例:
// debug.ts
function debugFunction(value) {
debugger; // 这里会暂停执行,允许在调试器中检查上下文
console.log("Debugging value:", value);
}
debugFunction("Debug me");
以下是一个优化示例,使用deno.cache
来缓存导入的模块:
// optimized_import.ts
import { cache } from "https://deno.land/x/deno.land_std@0.125.0/cache/mod.ts";
const cachedModule = await cache(
"https://deno.land/x/your_module@latest",
".cache",
);
// 现在可以从缓存中导入模块
import * as mod from `${cachedModule}/mod.ts`;