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)
配置文件通常包含以下部分:
- permissions: 定义运行时的权限。
- importMap: 设置模块的导入映射。
- compilerOptions: TypeScript编译器的选项。
- lintRules: Lint规则(如果使用deno-lint)。
- watch: 监听文件变化并自动重新运行。
- 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" });
}
-
导入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);
代码解析:
导入模块:
- 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.log
、console.error
以及使用debugger
语句配合IDE或浏览器的开发者工具进行。示例:
// debug.ts
function debugFunction(value) {debugger; // 这里会暂停执行,允许在调试器中检查上下文console.log("Debugging value:", value);
}debugFunction("Debug me");
性能优化
- 避免不必要的计算:只在需要时计算值,不要提前计算大量数据。
- 使用异步操作:对于I/O密集型任务,使用异步操作避免阻塞主线程。
- 缓存结果:对于重复计算的结果,可以考虑缓存。
- 使用类型检查:TypeScript的类型系统可以帮助避免运行时错误,提高代码质量。
- 限制权限: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计算机入门到高级架构师开发资料超级大礼包免费送!
相关文章:

Deno入门:Node.js的现代替代品
Deno 作为 Node.js 的现代替代品,提供了许多改进和创新,尤其是在安全性、模块系统和开发体验方面。虽然它仍处于发展阶段,但对于寻求简洁、安全和现代化 JavaScript/TypeScript 开发环境的开发者来说,Deno 是一个值得考虑的选择。…...

WIFI 万[néng]钥匙 v5.0.10/v4.9.80 SVIP版!
WiFi Master Key v5.0.10/v4.9.80 WIFI万[Nng]钥匙APP是一款专业的网络连接工具,设计宗旨在于为用户提供方便快捷的WiFi接入方案。本应用集成了覆盖全国的大量免费WiFi热点信息,确保用户能够在不同地区快速而稳定地连接到互联网。此外,该应用…...

JCR一区级 | Matlab实现TCN-BiLSTM-MATT时间卷积双向长短期记忆神经网络多特征分类预测
JCR一区级 | Matlab实现TCN-BiLSTM-MATT时间卷积双向长短期记忆神经网络多特征分类预测 目录 JCR一区级 | Matlab实现TCN-BiLSTM-MATT时间卷积双向长短期记忆神经网络多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.JMatlab实现TCN-BiLSTM-MATT时间卷积双…...

redis之发布与订阅
华子目录 什么是发布与订阅?常用命令psubscribe pattern1 [pattern2...]subscribe channel1 [channel2...]publish channel messagepunsubscribe pattern1 [pattern2...]unsubscribe [channel1 [channel2...]]pubsub subcommand argument1 [argument2...] 示例1示例…...

LLM主流开源代表模型
LLM主流开源大模型介绍 1 LLM主流大模型类别 随着ChatGPT迅速火爆,引发了大模型的时代变革,国内外各大公司也快速跟进生成式AI市场,近百款大模型发布及应用。 目前,市面上已经开源了各种类型的大语言模型,本章节我们…...

Openharmony的usb从框架到hdf驱动流程梳理
HDF框架实现了用户层与内核层进行通信的管理框架,关于其简易通信示例在以下两篇博文中有所介绍, 一个例子了解通过Openharmony的HDF框架实现简易驱动的流程https://blog.csdn.net/procedurecode/article/details/128906246 Openharmony的用户态应用通过HDF框架驱动消息机制…...

Apache Doris 基础 -- 数据表设计(数据模型)
Versions: 2.1 1、模型概览 本主题从逻辑角度介绍了Doris中的数据模型,以便您可以在不同的业务场景中更好地使用Doris。 基本概念 本文主要从逻辑的角度描述Doris的数据模型,旨在帮助用户在不同的场景更好地利用Doris。 在Doris中,数据在…...

“雪糕刺客”爆改“红薯刺客”,钟薛高给了消费品牌哪些启示?
夏日袭来,一支价格高昂却让人眼前一亮的雪糕,曾一度成为市场热议的焦点。然而,随着消费者对性价比的日益关注,曾经的“雪糕刺客”钟薛高,其创始人林盛近期以直播带货红薯开启他的还债之路,高打情怀“直播自…...

多输入多输出非线性对象的模型预测控制—Matlab实现
本示例展示了如何在 Simulink 中设计多输入多输出对象的闭环模型预测控制。该对象有三个操纵变量和两个测量输出。 一、非线性对象的线性化 运行该示例需要同时安装 Simulink 和 Simulink Control Design。 % 检查是否同时安装了 Simulink 和 Simulink Control Design if ~m…...

多项分布模拟及 Seaborn 可视化教程
多项分布 简介 多项分布是二项分布的推广,它描述了在 n 次独立试验中,k 种不同事件分别出现次数的离散概率分布。与二项分布只能有两种结果(例如成功/失败)不同,多项分布可以有 k 种(k ≥ 2)及…...

学计算机,我错了吗?
今天,我的一位朋友告诉我,终于找到一家小公司入职,年前 1 月辞职,本想休息一段时间,没成想,休息到 6 月份,现在程序员真的越来越难找工作了。 肯定有人在想,现在这种行情࿰…...

学习小心意——简单的循坏语句
for循坏 基本语法格式 for 变量 in 序列:代码块 示例代码如下 for i in range(10):print(i)#输出结果:0 1 2 3 4 5 6 7 8 9 简单案例代码如下 利用for语句遍历序列 # 遍历字符串打印每个字母 for letter in "python":print(letter)# 遍历列表并打印每个元素 a …...

C++ 类方法解析:内外定义、参数、访问控制与静态方法详解
C 类方法 类方法,也称为成员函数,是属于类的函数。它们用于操作或查询类数据,并封装在类定义中。类方法可以分为两种类型: 类内定义方法: 直接在类定义内部声明和定义方法。类外定义方法: 在类定义内部声明方法,并在…...

pytorch+YOLOv8-1
1.工具开发 2.idea配置pytorch环境 默认安装新版本torch pip install torch 3.pytorch验证 4. print(torch.cuda.is_available()) 输出结果为 False 说明我只能用cpu...

JavaScript 基础 - 对象
对象 对象是一种无序的数据集合,可以详细的描述描述某个事物。 注意数组是有序的数据集合。它由属性和方法两部分构成。 语法 声明一个对象类型的变量与之前声明一个数值或字符串类型的变量没有本质上的区别。 <script>let 对象名 {属性名:属性值…...

代码随想录第23天|回溯part3 组合与分割
39.组合总和 class Solution { public:vector<vector<int>> res;vector<int> path;void backTracking(vector<int>& candidates,int target,int sum,int n,int step){if(n > 150) return;if(sum > target) return;if(sum target){res.push_…...

nginx和proxy_protocol协议
目录 1. 引言2. HTTP server的配置3. Stream server的配置3.1 作为proxy_protocol的前端服务器3.2 作为proxy_protocol的后端服务器1. 引言 proxy_protocol 是haproxy开发的一种用于在代理服务器和后端服务器之间传递客户端连接信息的协议。使用 proxy_protocol 的主要优势是能…...

【pytorch】数据转换/增强后保存
数据转换 from PIL import Image from pathlib import Path import matplotlib.pyplot as plt import numpy as npimport torch import torchvision.transforms as Tplt.rcParams["savefig.bbox"] = tight # orig_im...

超越Devin!姚班带队,他们创大模型编程新世界纪录
超越Devin!SWEBench排行榜上迎来了新玩家—— StarShip CodeGen Agent,姚班带队初创公司OpenCSG出品,以23.67%的成绩获得全球第二名的成绩。 同时创造了非GPT-4o基模的最高纪录(SOTA)。 我们都知道,SWEBe…...

江苏大信环境科技有限公司:环保领域的开拓者与引领者
2009 年,江苏大信环境科技有限公司在宜兴环保科技工业园成立。自创立之始,该公司便笃定坚守“诚信为本、以质量求生存、以创新谋发展”这一经营理念,全力以赴为客户构建专业的工业有机废气治理整体解决方案,进而成为国家高新技术企…...

关于 Bean 容器的注入方式,99 % 的人都答不全!
引言:在使用 Spring 框架开发应用程序时,依赖注入是一个至关重要的概念。而对于 Bean 容器的注入方式,虽然我们可能都有一定的了解,但实际上很多人在被问及这个问题时可能并不能完整地回答。本文将深入探讨 Spring 中 Bean 容器的…...

Spring的@Async注解及其用途
Spring 的 Async 注解是 Spring Framework 4.2 版本引入的功能,它用于支持异步方法执行。当一个方法标注了 Async,Spring 会在一个单独的线程中调用该方法,从而不会阻塞主线程的执行。 Async 注解的用途: 提高性能:通…...

JS(DOM、事件)
DOM 概念:Document Object Model,文档对象模型。将标记语言的各个组成部分封装为对应的对象: Document:整个文档对象Element:元素对象Attribute:属性对象Text:文本对象Comment:注释对象 JavaScript通过DOM,就能够对HTML进行操作: 改变 HTML 元素的内…...

学习小心意——python的构造方法和析构方法
构造方法和析构方法分别用于初始化对象的属性和释放类占有的资源 构造方法_init_() 语法格式如下: class 类名:def __init__(self, 参数1, 参数2, ...):# 初始化代码self.属性1 参数1self.属性2 参数2# ... 示例代码如下 class Student:def __init__(self):s…...

GB/T 23995-2009 室内装饰装修用溶剂型醇酸木器涂料检测
溶剂型醇酸木器涂料是指以醇酸树脂为主要成膜物,通过氧化干燥成膜的溶剂型木器涂料适用于室内木制品表面的保护及装饰。 GB/T 23995-2009室内装饰装修用溶剂型醇酸木器涂料检测项目: 测试指标 测试方法 在容器中状态 GB/T 23995 细度 GB/T 6753.1 …...

Maven 中的 classifier 属性用过没?
最近训练营有小伙伴问到松哥一个关于 Maven 依赖的问题,涉及到 classifier 属性,随机问了几个小伙伴,都说工作中没用到过,因此简单整篇文章和小伙伴们分享下。 Maven 大家日常开发应该都有使用,Maven 中有一个比较好玩…...

Linux网络编程:传输层协议|UDP|TCP
知识引入: 端口号: 当应用层获得一个传输过来的报文时,这时数据包需要知道,自己应该送往哪一个应用层的服务,这时就引入了“端口号”,通过区分同一台主机不同应用程序的端口号,来保证数据传输…...

MongoDB CRUD操作:内嵌文档查询
MongoDB内嵌文档的查询 文章目录 MongoDB内嵌文档的查询使用点号.查询内嵌文档嵌套字段的相等匹配使用查询操作符进行匹配指定AND条件 嵌套文档的匹配使用 MongoDB Atlas 查询内嵌文档导航至集合指定查询过滤文档点击应用 可以使用下面几种方法查询MongoDB中的嵌入文档…...

JavaScript、Kotlin、Flutter可以开发鸿蒙APP吗?
自从去年华为宣布推出「鸿蒙Next」版本开始,标志着其操作系统的全面革新。鸿蒙Next将摒弃所有基于AOSP的代码,与Android系统彻底分离,实现完全自主的研发路径。通过精简约40%的冗余代码,鸿蒙Next致力于构建一个更高效、更流畅的系…...

刚体运动描述:欧拉角与四元数
在机器人学中,刚体的运动描述是非常重要的,特别是当我们需要精确控制机器人的姿态时。欧拉角和四元数是两种常用的描述刚体在三维空间中旋转的方法。下面将分别介绍这两种方法并给出其特点。 欧拉角 定义与特点: 定义:欧拉角是…...