原文:What’s Deno, and how is it different from Node.js?javascript
译者:朱林
阅读时间:5~7minjava
Node.js的做者Ryan Dahl,过去一年半的时间都在打造一个新的JavaScript运行环境Deno来解决Node的一些内在问题。node
不过不要误会,得益于JavaScript庞大的社区生态和使用范围,Node是一个很是不错的JavaScript运行环境。然而,Dahl 也认可在Node的某些方面他应该考虑得更全面一些,好比:安全性,模块机制,依赖管理等。webpack
在他的计划中,他并不会去预想Deno在短期内可以发展成一个多大规模的平台。固然咯,把时间调回2009年,JavaScript仍是人人都能取笑的一个有些怪异的小语言,也木有如今这么多语言特性。git
Deno是基于Google V8引擎构建的安全的TypeScript运行环境。 下面是构建Deno的一些物料:github
接下来看看Deno提供了哪些特性。web
Deno最重要的特性就是安全性。shell
相较于Node,Deno默认使用沙箱环境执行代码,这意味着运行环境没有操做如下模块权限:npm
让咱们瞅一眼Deno的权限系统是如何工做滴。编程
(async () => {
const encoder = new TextEncoder();
const data = encoder.encode('Hello world\n');
await Deno.writeFile('hello.txt', data);
await Deno.writeFile('hello2.txt', data);
})();
复制代码
这个脚本分别建立了两个名为hello.txt
和hello2.txt
的文件,并在其中写入Hello world
。可是这段代码运行在沙箱环境中,因此是没有文件系统的操做权限滴。
还有一点值得注意,在上面的脚本中咱们使用Deno命名空间来操做文件,而不像在Node中使用fs
模块。Deno命名空间提供了超多基础方法。不过使用Deno命名空间会致使咱们的代码失去了对浏览器的兼容性,这个问题咱们晚点再聊。
使用下面的命令执行上述脚本:
$ deno run write-hello.ts
复制代码
执行以后,咱们会收到下面的提示:
Deno requests write access to "/Users/user/folder/hello.txt". Grant? [a/y/n/d (a = allow always, y = allow once, n = deny once, d = deny always)]
复制代码
实际上,基于上面建立文件的脚本咱们会收到两次来自沙箱环境的权限提示。不过若是咱们选择allow always
选项,就只会被询问一次啦。
若是咱们选了deny
,会抛出一个PermissionDenied
的错误,若是咱们没写错误处理逻辑的话,进程在此时就被终止啦。
若是咱们用下面的命令来执行脚本:
deno run --allow-write write-hello.ts
复制代码
会在没有提示的状况下建立这两个文件。
Deno针对文件系统的命令行标志位,除了--allow-write
,还有--allow-net
/--allow-env
/--allow-run
,分别用来开启针对网络、系统环境变量和操做子进程的权限。
Deno使用浏览器同样的方式,经过URL来加载模块。不少人第一次见到在服务端的import语句中见到URL会感到有点困惑,但对我来讲这还蛮好理解的:
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
复制代码
你以为经过URL来引入模块会有啥大不了的吗?答案其实蛮简单的:经过使用URL来加载模块,Deno就能够避免引入一个相似npm
的中心化系统来发布package,npm
最近受到了不少吐槽。
经过URL来引入代码,可让包的做者们使用本身最喜好的方式来维护和发布本身的代码。不再会有package.json
和node_modules
了。
当咱们启动应用以后,Deno会下载全部被引用的文件,并将它们缓存到本地。一旦引用被缓存下来,Deno就不会再去下载它们了,除非咱们使用-- relaod
标志位去触发从新下载。
还有几个问题值得咱们讨论一哈:
因为没有了一个中心化的包管理站点,那些存放模块的站点可能由于各类各样的缘由挂掉。若是在开发甚至生产环境出现这种状况是很是危险滴!
咱们在上一节提到,Deno会缓存好已下载的模块。因为缓存是存放在咱们的本地磁盘的,Deno的做者建议将这些缓存提交到代码仓库里。这样一来,即便存放引用的站点挂了,开发者们仍是可使用已经下载好的模块(只不过版本是被锁住的啦)。
Deno会把缓存存储在环境变量$DENO_DIR
所指定的目录下,若是咱们不去设置这个变量,它会指向系统默认的缓存目录。咱们能够把$DENO_DIR
指定咱们的本地仓库,而后把它们提交到版本管理系统中(好比:git
)
老是敲URL显得有点XX,还好,Deno提供了两种方案来避免咱们成为XX。
第一种,你能够在本地文件中将已经引用的模块从新export出来,好比:
export { test, assertEquals } from "https://deno.land/std/testing/mod.ts";
复制代码
假如上面这个文件叫local-test-utils.ts
。如今,若是咱们想再次使用test
或者assertEquals
方法,只须要像下面这样引用它们:
import { test, assertEquals } from './local-test-utils.ts';
复制代码
看得出来,是否是经过URL来引用它们并非最重要的啦。
第二种方案,建一个引用映射表,好比像下面这样一个JSON文件:
{
"imports": {
"http/": "https://deno.land/std/http/"
}
}
复制代码
而后把它像这样import到代码里:
import { serve } from "http/server.ts";
复制代码
为了让它生效,咱们还须要经过--importmap
标志位让Deno来引入import映射表:
$ deno run --importmap=import_map.json hello_server.ts
复制代码
版本管理必须由包做者来支持,这样在client端能够经过在URL中设置版本号来下载:https://unpkg.com/liltest@0.0.5/dist/liltest.js
。
Deno有计划作到兼容浏览器。从技术上讲,在使用ES module的前提下,咱们不须要使用任何相似webpack的打包工具就能在浏览器上运行Deno代码。
不过呢,你可使用相似Babel这样的工具能够把代码转化成ES5版本的JavaScript,这样能够兼容那些不支持全部最新语言特性的低版本浏览器中,带来的后果就是最终文件里有不少不是必须的冗余代码,增大代码的体积。
结果取决于咱们的主要目的是啥。
不须要任何配置文件就能在Deno中轻易地使用TypeScript。固然咯,你也能够编写纯JavaScript代码,并使用Deno去执行它。
Deno,做为一个新的TypeScript和JavaScript的运行环境,是一个很是有趣的技术项目,而且至今已经稳定发展了一段时间。可是距离在生产环境中去使用它还有比较长的一段路要走。
经过去中心化(或者翻译成分布式?)的机制,把JavaScript生态系统从npm这样中心化的包管理系统中解放了出来。
Dahl但愿在这个夏天快结束的时候可以发布1.0版本,因此若是你对Deno将来的新进展感兴趣的话,能够给它个star。
最后还有一个日志系统的广告,你们能够去原文查看。
关注【IVWEB社区】公众号获取每周最新文章,通往人生之巅!