Deno笔记

前言:

Deno是通用JavaScript/TypeScript编程环境,集成了很多最好的开源技术,在一个小执行文件中提供了全面的解决方案。

作为Node.js的创始人,Ryan Dahl又打造了Deno。Deno利用了2009年Node.js发布之后JavaScript的新增特性,同时也解决了Ryan在其“Node.js十大遗憾”(演讲)中提到的设计缺陷。有人称其为Node.js的后续者,但作者本人并没有这么说过。

与Node.js使用C++不同,Deno是使用Rust开发的,构建在Tokio(https://tokio.rs/,Rust异步运行时)平台之上。但与Node.js类似,Deno也使用V8引擎运行JavaScript。内置TypeScript是Deno的是一个明显特征。尽管需要先编译成JavaScript再运行,但这个过程在内部完成,因此看起来就像Deno原生支持TypeScript一样。

1. 上手

根据官网主页(https://deno.land/)的指导,可以下载Deno。要升级到新版本,运行deno upgrade。如果你之前安装的Deno版本过低,可以尝试再次运行终端脚本安装。

要了解Deno子命令,使用如下任意一命令。

deno [subcommand] -h:显示摘要

deno [subcommand] --help:显示详细信息

本文将介绍Deno 1.0的重点特性,包括使用最新语法应用这些特性的示例。我们会尽可能使用TypeScript,等价的JavaScript当然也没问题。

相信看完这篇文章你一定会喜欢上Deno。本文将正式带领读者进入Deno开发的大门。

2. 安全

Deno默认安全。相比之下,Node.js默认拥有访问文件系统和网络的权限。

要在没有授权的情况下运行一个需要启动子进程的程序,比如:

deno run file-needing-to-run-a-subprocess.ts

如果需要相关权限,你会看到一条警示消息:

error: Uncaught PermissionDenied: access to run a subprocess, run again with the --allow-run flag

Deno使用命令行选项显式允许对系统不同部分的访问。最常用的包括:

环境

网络

文件系统读/写

运行子进程

要了解包含示例的全部权限,运行deno run -h。

最佳实践是对read、write和net使用权限白名单。这样可以更具体地指定允许Deno访问什么。例如,要授予Deno对/etc目录的只读权限,可以这样:

deno --allow-read=/etc

2.1 使用权限的快捷方式

每次运行应用都要授权很快就会觉得麻烦。为此,可以使用如下方法。

1. 允许所有权限

可以使用--allow-all或快捷方式-A。不推荐这么做,因为这么做就无法控制特定的权限。

2. 写个bash脚本

写一个bash脚本来运行应用,授权该应用所需的最低权限。

#!/bin/bash
// 允许运行子进程及文件系统写权限
deno run --allow-run --allow-write mod.ts

这个方法的缺点是可能要针对运行、测试和打包都分别写一个脚本。

3. 使用任务运行器

可以使用GNU工具make创建包含一组Deno命令及相关权限的文件。也可以使用特定于Deno的版本Drake(https://deno.land/x/drake/)。

4. 安全可执行的Deno程序

使用deno install安装一个包含其执行所需权限的Deno程序(https://github.com/denoland/deno/tree/master/docs)。安装之后,这个程序的路径就在$PATH里。

3. 标准库


Deno标准库(https://deno.land/std/)包含常用的模块,由Deno项目维护,保证可以在Deno中使用。标准库涵盖最常用的工具,API风格及特性镜像了Go语言的标准库。

JavaScript一直因缺少标准库而饱受诟病。用户不得不为此重复“发明轮子”,开发者经常要搜索npm仓库来寻找解决常见问题的模块,而这些模块本来就是应该由平台提供的。

像React这样解决复杂问题的第三方包另当别论,但像生成UUID(https://en.wikipedia.org/wiki/Universally_unique_identifier)这样简单的任务最好还是使用标准库来完成。这些小库可以作为更大库的组件,让开发更快、惊吓更少。不知道有多少次一个流行的库突然宣布废弃,用户只能自己维护或者再去寻找新的替代库。调查显示,常用的开源软件包中有10-20%已经不再积极维护。

3.1 内置模块及对应的npm包

 
Deno模块 说明 npm包
colors 给终端输出设置颜色 chalk、kleur、colors
datetime 帮助处理JavaScript的Date对象  
encoding 增加对base32、二进制、csv、toml和yaml等外部数据结构的支持  
flags 帮助处理命令行参数 minimist
fs 帮助实现文件系统操作  
Http 支持通过HTTP访问本地文件 http-server
log 用于创建日志 winston
testing 用于单元测试和基准测试 uuid
ws 帮助创建WebSocket客户端/服务器 Ws
     

4. 内置TypeScript

TypeScript是JavaScript的超集,增加了显式类型声明。任何有效的JavaScript也是有效的TypeScript,因此把你的代码转换为TypeScript不需要什么代价。只要把扩展名改为.ts,然后再加上类型就可以了。

在Deno中使用TypeScript,你什么也不用做。如果没有Deno,那你必须先把TypeScript编译为JavaScript,然后才能运行。Deno内部帮你进行编译,因此让你使用TypeScript更容易。

4.1 使用自己的tsconfig.json

熟悉TypeScript的人可能知道要使用tsconfig.json文件指定编译选项。但在使用Deno时这个文件不是必需的。因为Deno有自己默认的配置。如果你要使用自己的tsconfig.json,而其中的选项与Deno有冲突,你会看到警示消息。

这个特性要求使用-c选项并指定你自己的tsconfig.json。

deno run -c tsconfig.json [file-to-run.ts]

关于默认tsconfig.json的细节,可以参考Deno手册(https://github.com/denoland/deno/tree/master/docs)。

如果你跟多数开发者一样,那听说Deno默认使用strict模式一定会高兴。除非有人故意重写这个设置,否则Deno会尽其所能将代码中的草率之处报告给用户。

5. Deno极力贴近Web标准

Web标准的制定时间很长,一旦发布,谁也不能视而不见。虽然各种框架你方唱罢我登场,但Web标准则始终如一。在学习Web标准上花费的时间永远不会浪费,因为没有人胆敢推翻Web。在可以预见的未来几十年,甚至到你职业生涯的终点,Web仍将继续存在和发展。

fetch是用于获取资源的Web API。浏览器中有一个JavaScript方法叫fetch()。如果你想在Node.js中使用这个标准API,需要依赖第三方的Node Fetch(https://github.com/node-fetch/node-fetch)。而在Deno中,这个API是内置的,就像浏览器中的版本一样,开箱即用。

Deno 1.0提供以下兼容Web的API。

addEventListener

atob

btoa

clearInterval

clearTimeout

dispatchEvent

fetch

queueMicrotask

removeEventListener

setInterval

setTimeout

AbortSignal

Blob

File

FormData

Headers

ReadableStream

Request

Response

URL

URLSearchParams

console

isConsoleInstance

location

onload

onunload

self

window

AbortController

CustomEvent

DOMException

ErrorEvent

Event

EventTarget

MessageEvent

TextDecoder

TextEncoder

Worker

ImportMeta

Location

如上API都在程序的顶级作用域。这意味着如果你不使用Deno()命名空间中的任何方法,你的代码应该同时可以在Deno和浏览器中运行。虽然Deno的这些API并不是100%符合Web标准,但这对前端开发者依然是重大利好。

6. ECMAScript模块

Deno相比于Node.js的一个主要变化是使用了正式的ECMAScript模块标准,而不是老旧的CommonJS。Node.js直到2019年底才在13.2.0中支持ECMAScript模块,即便如此支持仍不完善,并且还需要包含有争议的.mjs扩展名。

Deno通过在其模块系统中拥抱现代Web标准与过去挥手作别。模块可以使用URL或者包含强制扩展名的文件路径来引用。例如:

import * as log from "https://deno.land/std/log/mod.ts";
import { outputToConsole } from "./view.ts";

6.1 使用扩展名的问题

Deno希望模块包含文件扩展名,但TypeScript不希望,

使用扩展名符合逻辑,也是一种显而易见的方式。可惜现实总比理想要复杂。目前为止,可以使用Visual Studio Code Deno扩展(https://marketplace.visualstudio.com/items?itemName=axetroy.vscode-deno)在Deno项目中解决这个问题。

TypeScript创始人似乎对这个问题有自己的看法。在最终抛弃CommonJS之前,我认为这个问题不会有简单的解决方案。

对于睿智但上了点年纪的编程大神们,我们还需要多一点耐心。但愿他们早日摒弃这些过气的格式,对那些死抓住它们不放而伤害我们的家伙降下惩罚。

7. 包管理

Deno的包管理方式已经发生了天翻地覆的变化。不再依赖中心化的仓库,Deno的包管理以去中心化为特色。任何人可以像在Web上托管任何类型的文件一样托管一个包。

像npm这样的中心化仓库有好处也有不足,这方面也是Deno饱受争议之处。

7.1 Deno新的包含管理机制
导入一个包变得如此简单可能会吓到你。

import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

下面我们来分析一下变化。

不再有中心化的包管理器,而是直接从Web上导入ECMAScript模块。

不再有“魔法般”的Node.js模块解析。现在,直观的语法更容易定位来源。

不再有node_modules目录。相反,依赖下载后会藏身于你的硬盘,你看不到。如果想刷新缓存再次下载,只要在命令后面加上--reload。

如果想把依赖下载到项目代码附近而不是使用全局缓存,可以使用$DENO_DIR环境变量。

————————————————
版权声明:本文为CSDN博主「奇舞周刊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qiwoo_weekly/java/article/details/106066302

猜你喜欢

转载自www.cnblogs.com/kuailingmin/p/12904627.html