程序运行依赖的重要文件版本不对_Deno核心模块:灵活依赖&安全沙箱

        Deno 的目标不是兼容 Node,而是兼容浏览器。Deno 不是要取代 Node.js,也不是下一代 Node.js,也不是要放弃 npm 重建 Node 生态。比如react和vue的存在,两个框架都很好,并不是谁要消灭谁,我们可以哪个合适用哪个,想用哪个用哪个。deno 的目前是要拥抱浏览器生态。

        前期文章讲解过《初识Deno》(https://mp.weixin.qq.com/s/ZlnbBITXDqxpwLf32n9-bw)和《从模块谈Deno和Node的区别(https://mp.weixin.qq.com/s/LshySTHs7rlMsBcmx6qVuw) 。本期内容主要围绕Deno核心模块中比较重要的两个部分讲解:安全沙箱机制和Deno依赖引入管理。

       标题提到过核心模块,讲解一下我个人对于Deno模块的理解,我的划分:第三方库、标准库、底层运行时、安全沙箱机制和依赖管理。顺带我们可以看看Deno源码项目目录的划分(本次所针对的都是version1.5.3的版本),主要包含以下部分:

bc30e79a820680a283e5cfc8401a1f2c.png 一、灵活依赖

        Deno天然支持ECMAScript 6(以下简称es6),可以直接用es6 的模块引入方式(即import/export,后面简称es module)。Deno 依靠 es module 引入URL 来承载和导入程序包。这种引入插件的方式非常灵活,我们可以直接创建软件包而无需在 NPM 这样的存储库中发布它们。

        下面我们通过官方简单demo来展现Deno通过es module 引入URL请求资源并且执行,当我们运行代码` deno run https://deno.land/std/examples/welcome.ts `,会正确返回如下图的结果。

d299caf2d220a1ba0a07fb759f16dfe8.png

          下图是官方demo中的代码:

8415c7c463fda5a4d44d250fed9c4fce.png

        可以看到上面项目我们本地没有任何代码或者项目,只是运行了一个远程的官方demo文件,在控制台就直接执行并且正确执行结果。不需要自己去下载要引入的代码,‘拿来主义’直接执行就好了,非常省事。

        默认情况下,缓存中的模块将被重用,而无需获取或重新编译它。那是否存在缓存不被更新依赖到旧代码的问题?肯定会的。有时候我们并不希望使用缓存的模块,我们可以强制 deno 重新下载模块并重新编译到缓存中。可以使用 deno cache 子命令的--reload 选项来使本地缓存无效。

        带着问题学习可能会更易于理解,我们来看看下一个问题。由于Deno直接引入外部代码或者本地代码,没有包管理器的情况下管理外部依赖关系就会导致问题。会不会在用的地方引入会导致引入文件比较杂乱、项目越大越难维护、重复引入等问题?答案是肯定的。

        在 Deno 中解决这些问题的标准做法是创建一个 deps.ts 文件。此文件中引用了所有必需的远程依赖关系,并且重新导出了所需的方法和类。本地模块从 deps.ts 导入所需方法和类,而不是远程依赖。这样就可以轻松跨大型代码库更新模块,并解决“程序包管理器问题”。开发依赖项也可以在单独的 dev_deps.ts 文件中进行管理。

        deps.ts中引入文件示例图:

5133a22307bcd07334576bdabe98cfa5.png         depsTest.ts中引入文件示例图: 5733f4369edfaf2de4e1330c6d2638ac.png

        depsTest.ts 运行示例图:

1405435e965d090f4d5a9b6f0eecc487.png

78f6cb440022833b6880b160456027ee.png

        可以看到上面可以正确运行出结果,感觉是未来的趋势,精简而干练。

        那么Deno为何可以通过URL直接引入其他资源直接执行呢?deno有自己的缓存远端资源的逻辑。下面我们来看看deno/core代码模块的https_catsh.rs部分源码。

        即使作为前端人员不是很懂rust,从下面源码大致可以get到两个方法:base_url_tofilename和url_to_filename。base_url_tofilename将请求的url解析后返回成`主域名+文件hash`的字符串返回,url_to_filename直接调用的base_url_tofilename,返回一个包含缓存文件名的数组,并且该模块代码会进行文件内容的写入等一些列操作。get_cache_filename是总出口文件,供core/http_fetcher.rs文件模块使用。

f7e7b141d5eeb63b4ac3fd6bb71877b9.png 2ec6a32beaa7205b8b1298cab1c262c2.png

726815821507abb6111582a985225a98.png

        下图是经过base_url_tofilename方法处理后的前后文件名的对应关系。

b3faf32b483a0cfe055e6bf03be995d1.png

        文件模块core/http_fetcher.rs,可以起一个http服务,查询文件是否在本地存在。如果文件存在,就直接从本地拿文件资源,如果本地缓存中没有文件,就通过http请求与远端建立链接,获取远端资源写入到本地进行缓存。

6cd72ce1b338eafc9c2345b0b16ebb5a.png

        下面代码则是缓存处理的初始化配置信息。默认是从缓存中获取数据,不需要中心加载所有数据,以及只有使用权限。

fbf7ebd90f36a876e40c86fbce66d941.png

一 、安全沙箱机制

        URL的方式直接引入文件会不会导致和node一样的权限紊乱问题?Deno的答案是“NO”。Deno有自己的安全沙箱机制。

       首先对沙箱进行简单的释义。沙箱是一个限制程序运行的环境,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。

        Deno 的安全沙箱机制来自 web。安全沙箱机制是 web 的特色,浏览器中运行的 js 代码可能来自任何地方,而且都不是我们主动下载运行的,也不一定这些代码都是受信任的,但是我们依然敢运行这些代码。是因为浏览器的沙箱机制保证了这些 js 代码不会访问系统资源。

        Deno的安全沙箱机制主要包含文件读取权限、网络权限、系统权限。默认我们代码是没有访问这些权限的,在命令行参数中为 Deno 进程授权后才能访问安全敏感的功能。在实际开发过程中我们可以加上--allow-all (允许所有权限,无安全限制)、-allow-env (允许环境访问,比如读取和设置环境变量)、--allow-net= (允许网络访问)、--allow-write=(允许写入文件系统)或 --allow-read=(允许读取文件系统)等权限,赋予我们的代码一定的权限。

        如下代码为rust中判断是否有创建文件夹权限,有权限才可循环创建文件夹,否则提示没权限。

     23ce7a7b238754a53b810e18accf224d.png

        如下图,permission.rs文件中会对各项权限进行判断。判断有没有写入权限,有没有网络权限等。

192c52dba69f8beb2bd6322eeacf3389.png

        在deno使用过程中我一直有个疑惑:为什么deno run 'https://deno***'下的文件没提示需要网路权限,在查看源码发现是deno内部处理了对deno网络权限权限的白名单,如下图所示:

e58b00dfa011f6c2b42fb1eb283f5604.png

        最后,作为文章的收尾,提一下作为deno rust语言入口文件的main.ts,通过main方法把所有代码模块串联起来,运行出我们所看到的deno效果。主入口方法如下图所示。

f47ced54f0b56959c798e2c18582f1ad.png

        由于对rust语言以及deno的原理熟悉度有限,本编文章主要讲解到这里。如果文章中有不合适的地方或者讲解的不对的,欢迎留言交流。一起学习Deno,fighting~~ 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值