Deno入门:Node.js的现代替代品

Deno 作为 Node.js 的现代替代品,提供了许多改进和创新,尤其是在安全性、模块系统和开发体验方面。虽然它仍处于发展阶段,但对于寻求简洁、安全和现代化 JavaScript/TypeScript 开发环境的开发者来说,Deno 是一个值得考虑的选择。随着社区的持续发展,Deno 的潜力和影响力有望进一步扩大。

Deno基础知识

  • 内置的安全模型:Deno有严格的权限控制,如读写文件、网络访问等都需要明确的权限许可。
  • TypeScript支持:Deno默认支持TypeScript,可以提供更好的类型检查和开发体验。
  • ES模块:Deno使用URL或导入映射来导入模块,不同于Node.js的CommonJS模块系统。
命令行工具:

deno run:执行单个文件。
deno test:运行测试。
deno fmt:代码格式化。
deno lint:代码风格检查。

配置文件

Deno的配置文件主要以deno.json为主,它可以包含多个配置选项来定制运行时的行为。而环境变量主要影响Deno的全局配置,如日志级别、缓存目录等。

Deno配置文件 (deno.json)

配置文件通常包含以下部分:

  1. permissions: 定义运行时的权限。
  2. importMap: 设置模块的导入映射。
  3. compilerOptions: TypeScript编译器的选项。
  4. lintRules: Lint规则(如果使用deno-lint)。
  5. watch: 监听文件变化并自动重新运行。
  6. reload: 自动重新加载模块。
{"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

创建HTTP服务器

在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" });
}
  1. 导入serve函数:import { serve } from “https://deno.land/std/http/server.ts”;从Deno的标准库中导入serve函数,这个函数用于创建HTTP服务器。

  2. 启动服务器:const s = serve({ port: 8000 });创建并启动服务器,监听8000端口。s是一个可迭代对象,代表服务器接收的每个请求。

  3. 打印服务器信息:console.log(“Server is running on http://localhost:8000”);告知用户服务器已经启动,并提供访问地址。

  4. 处理请求:for await (const req of s)是一个异步迭代器,它会等待并处理每一个到达的HTTP请求。req是ServerRequest类型的实例,包含了请求的信息。

  5. 响应请求:req.respond({ status: 200, body: “Hello, World!\n” });向客户端发送响应。status是HTTP状态码(这里是200,表示成功),body是响应体(这里是字符串"Hello, World!\n")。

  6. 运行服务器:在终端中,使用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);

代码解析:

导入模块:
  • assert用于断言,确保HTTP请求成功。
  • parseJson用于将接收到的文本转换为JSON对象。
定义fetchData函数:
  • fetch(url)异步地发起HTTP GET请求到指定的URL。
  • response.ok检查HTTP状态码是否在200-299之间,表示请求成功。
  • response.text()获取响应体的文本内容。
  • parseJson(text)将文本内容解析为JSON对象。
  • console.log(data)打印解析后的数据。
调用fetchData:
  • fetchData(remoteDataURL)使用示例URL调用函数,获取远程数据。
运行脚本:
  • 在终端中,使用deno run --allow-net fetch_data.ts运行脚本。–allow-net是必需的,因为网络访问是默认禁止的。

文件系统操作

// 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处理:

// 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();
使用deno.land/x第三方模块:
// 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的模块仓库,提供了一些社区维护的模块。

使用WebSocket

在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
服务器端:
  • 导入Server类并创建一个实例,监听8080端口。
  • 当有新的客户端连接时,触发connection事件,记录日志并设置消息处理器。
  • 对于每个接收到的消息,服务器会回送一条确认消息给客户端。
  • 当客户端断开连接时,触发close事件。
客户端:
  • 使用connect函数连接到服务器指定的URL。
  • 设置open事件处理器,当连接建立时发送一条消息给服务器。
  • 设置message事件处理器,接收并打印来自服务器的消息。
  • 设置close事件处理器,记录连接关闭的事件。

错误处理和调试

错误处理

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.logconsole.error以及使用debugger语句配合IDE或浏览器的开发者工具进行。示例:

// debug.ts
function debugFunction(value) {debugger; // 这里会暂停执行,允许在调试器中检查上下文console.log("Debugging value:", value);
}debugFunction("Debug me");

性能优化

  1. 避免不必要的计算:只在需要时计算值,不要提前计算大量数据。
  2. 使用异步操作:对于I/O密集型任务,使用异步操作避免阻塞主线程。
  3. 缓存结果:对于重复计算的结果,可以考虑缓存。
  4. 使用类型检查:TypeScript的类型系统可以帮助避免运行时错误,提高代码质量。
  5. 限制权限:Deno的权限模型允许你精确控制代码的访问权限,避免不必要的资源消耗。

以下是一个优化示例,使用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`;

2500G计算机入门到高级架构师开发资料超级大礼包免费送!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/21796.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【封装】Unity切换场景不销毁物体

在切换场景时,如果物体不需要销毁,可以直接使用下方脚本 代码 public class DontDestroyLoader : MonoBehaviour{ //所有不销毁的物体预制体[SerializeField] private GameObject[] dontDestroyPrefabs;//实例化预制体public void Load(){foreach (var …

Linux CFS调度器简介

文章目录 前言一、概要二、实现2.1 简介2.2 算法实现2.3 内核源码 三、特点四、调度策略五、调度类参考资料 前言 早期的Linux调度器采用了简化的设计,显然并不针对具有许多处理器甚至超线程的大规模架构。Linux 1.2调度器使用循环队列对可运行任务进行管理&#x…

flink实战--大状态任务调优指南

Flink 状态(State)简介 在 Flink 中,状态管理是流处理应用的核心概念之一,它允许算子(operators)在处理事件时保持和操作状态信息。在 Flink 中,状态可以被视为算子的“记忆”,它使得算子能够在处理无界流数据时保持对历史数据的跟踪。状态可以是简单的键值对,也可以是…

昆仑万维官宣开源2000亿稀疏大模型Skywork-MoE

6月3日,昆仑万维宣布开源2千亿稀疏大模型Skywork-MoE,性能强劲,同时推理成本更低。 据「TMT星球」了解,Skywork-MoE基于之前昆仑万维开源的Skywork-13B模型中间checkpoint扩展而来,是首个完整将MoE Upcycling技术应用…

北京Profinet转Modbus网关配置调试详解

一、背景:在工业自动化系统中,PLC(可编程逻辑控制器)与流量计之间的通信是非常重要的,以确保数据准确传输并实现控制功能。然而,由于PLC和流量计可能采用不同的通信协议(如Profinet和Modbus&…

探索Java的DNA-JVM字节码深度解析

引言 在Java的世界里,JVM(Java虚拟机)是我们程序运行的心脏。而字节码,作为JVM的血液,携带着程序的执行指令。今天,我们将深入探索Java字节码的奥秘,一窥JVM如何将人类可读的代码转化为机器可执…

洛谷 P1438 无聊的数列

题意 给定一个序列 A ( A 1 , A 2 , ⋯ , A n ) A(A_1,A_2,\cdots,A_n) A(A1​,A2​,⋯,An​)。 现在进行 m m m次操作,分为以下两种: 1 l r k d:给定一个长度为 r − l 1 r-l1 r−l1的等差序列,首项为 k k k,公差为 d d d&am…

【小白向】微信小程序解密反编译教程

# 前言 最近笔者有做到微信小程序的渗透测试,其中有一个环节就是对微信小程序的反编译进行源码分析,所谓微信小程序反编译,就是将访问的小程序进行反向编译拿到部分源码,然后对源码进行安全审计,分析出其中可能存在的…

图形学初识--颜色混合

文章目录 前言正文为什么要有颜色混合?颜色混合常见实现方式?上述颜色混合注意点 结尾:喜欢的小伙伴点点关注赞哦! 前言 本章节补充一下颜色混合的内容,主要包含:为什么要有颜色混合?颜色混合常实现方式&a…

BGP——边界网关路由协议

BGP -边界网关路由协议 OSPF RIP EIGRP AS——自治系统 标准编号16位二进制 0-65535 1-64511公有 64512 -私有 扩展编号 32位二进制 动态路由协议: GP ——内部网关路由协议 —— AS之内 或企业网、局域网 RIP OSPF EIGRP EGP-外部网关路由协议 - …

Centos 7 安装刻录至硬件服务器

前言 在日常测试中,会遇到很多安装的场景,今天给大家讲一下centos 7 的安装,希望对大家有所帮助。 一.下载镜像 地址如下: centos官方镜像下载地址https://www.centos.org/download/ 按照需求依次点击下载 二.镜像刻录 镜像刻…

idea springboot woff/woff2/eot/ttf/svg等小图标不显示的问题 - 第515篇

历史文章(文章累计500) 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《…

Shopify 独立站监控观测最佳实践

Shopify 简介 Shopify 是一个全球领先的电子商务平台,它为商家提供了一整套在线商店解决方案。自 2006 年成立以来,Shopify 已经帮助数百万商家在全球范围内建立和发展他们的在线业务。 监控观测 Shopify 站点对于确保业务连续性、优化用户体验和提高运…

python虚拟环境venv的安装--ubuntu

venv是Python内置的虚拟环境管理工具 1.安装python3-venv包: sudo apt install python3.12-venv2.创建虚拟环境(在项目目录下) python3 -m venv venv3. 激活虚拟环境: source venv/bin/activate4.在虚拟环境中安装所需的库&am…

Linux shell编程学习笔记56:date命令——显示或设置系统时间与日期

0 前言 2024年的网络安全检查又开始了,对于使用基于Linux的国产电脑,我们可以编写一个脚本来收集系统的有关信息。在收集的信息中,应该有一条是搜索信息的时间。 1. date命令 的功能、格式和选项说明 我们可以使用命令 date --help 来查看 d…

python 虚拟环境安装及python包库安装

python 虚拟环境安装及python包库安装 安装虚拟环境的方式注意事项 安装虚拟环境的方式 切记尽量不要混用 pip 安装 对于pip安装,使用命令如下 下载virtualenv 工具 pip install virtualenv 创建虚拟环境并激活环境virtualenv venv source ./venv/bin/activate co…

Kafka之Broker原理

1. 日志数据的存储 1.1 Partition 1. 为了实现横向扩展,把不同的数据存放在不同的 Broker 上,同时降低单台服务器的访问压力,我们把一个Topic 中的数据分隔成多个 Partition 2. 每个 Partition 中的消息是有序的,顺序写入&#x…

LeetCode刷题:反转链表

leetCode真题 206. 反转链表 属于基础简单题目 常见的做法有递归和while循环 递归 // 1. 递归参数和返回值public static ListNode reverseList(ListNode head) {// 1. 递归终止条件if (head null || head.next null) {return head;}// 递归逻辑ListNode last reverseL…

达梦数据库相关SQL及适配Mysql配置总结

🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…

解决Python导入第三方模块报错“TypeError: the first argument must be callable”

注意以下内容只对导包时遇到同样的报错会有参考价值。 问题描述 当你尝试导入第三方模块时,可能会遇到如下报错信息: TypeError: the first argument must be callable 猜测原因 经过仔细检查代码,我猜测这个错误的原因是由于变量名冲突所…