上文说过,deno目前最大的问题是生态,也就是说仍无奈无缝继承nodejs的生态。那它也意味着能够应用一部分nodejs的资源。
以AST(形象语法树)为例,它在底层工作时还是很有必要的,咱们可能会用它写个小工具,实现一些简略的代码转换。但咱们在deno.land中查找第三方库,却没有找到适合的。
怎么办?
这时你首先想到的不该是“正是我辈大展身手造轮子的时候到了”,而是应该想,node的npm包是不是能够复用?
node版本
AST有各种实现版本,比拟闻名的是babel。这里我找两个简略的esprima和escodegen。
const esprima = require('esprima');const escodegen = require('escodegen');const encodeJs = function () { const str = ` global.x = 10; name += '-abc'; age = 12; `; const AST = esprima.parse(str); // console.log(AST); // console.log(AST.body[0].expression.left.object.name); // console.log(result.body[0].consequent.body[0].expression.left); AST.body.splice(0, 1); // remove global.x = 10; const originReback = escodegen.generate(AST); console.log(originReback); // name += '-abc';age = 12;};encodeJs();
咱们先在npm上看下这两个包的依赖状况:
一个零依赖,一个依赖了5个包。还是很有心愿通过CDN本义过去的。
deno版本
咱们试试CDN(通常有https://esm.sh/和https://cdn.skypack.dev/两个,这里任选一个)转下:
https://cdn.skypack.dev/esprima
https://cdn.skypack.dev/escodegen
仿佛是能够的,于是咱们能够试下:
import * as esprima from 'https://cdn.skypack.dev/esprima';import * as escodegen from "https://cdn.skypack.dev/escodegen";const encodeJs = function () { const str = ` global.x = 10; name += '-abc'; age = 12; `; const AST = esprima.parse(str); AST.body.splice(0, 1); // remove global.x = 10; const originReback = escodegen.generate(AST); console.log(originReback); // name += '-abc';age = 12;};encodeJs();
执行deno run xx.js,胜利!
真是个欢快的音讯。这意味着咱们不须要再造轮子。这样即便这两个包有什么bug,你只须要去github提issue,到时候降级版本就行了。
留神
不过有点儿须要留神,假如你要在我的项目中应用,最好将版本号写上,比方:
import * as esprima from 'https://cdn.skypack.dev/esprima@v2.0.0';
但这样还不够,如果你要应用deno的lock.json文件来保障我的项目各成员或各个环境都能应用雷同的版本,咱们所用的这个CDN并不能保障它的hash值不变动(也就是说隔断工夫对应的hash值会变动,也会导致deno cache --lock=lock.json校验失败),即便版本号是固定的。
那么应该怎么办呢?
再回头认真看下面CDN生成的文件内容:
这里有个Pinned URL,它便是正解。
所以,最终的代码变成这样:
import * as esprima from 'https://cdn.skypack.dev/pin/esprima@v4.0.1-2bFId5CSQMZAdjdZliQ2/mode=imports/optimized/esprima.js';import * as escodegen from "https://cdn.skypack.dev/pin/escodegen@v2.0.0-MB39rvARiyYcecqDvQhe/mode=imports/optimized/escodegen.js";const encodeJs = function () { const str = ` global.x = 10; name += '-abc'; age = 12; `; const AST = esprima.parse(str); AST.body.splice(0, 1); // remove global.x = 10; const originReback = escodegen.generate(AST); console.log(originReback); // name += '-abc';age = 12;};encodeJs();
毛病
咱们应用deno,举荐间接应用TS,但这个包没有ts文件,也就没有类型文件。到github上看下:
果然是用js写的。
针对这种状况,咱们要么这么忍了,要么只能本人给写个.d.ts文件了。
typescript类型推断
对于自身是用ts写的npm包,以jwfetch为例,只须要在前面加个?dts即可,如:
import { BaseAjax } from "https://cdn.skypack.dev/jwfetch?dts";
运行代码,控制台显示:
咱们看到,类型文件.d.ts都下载下来了。这样类型推断就有了。
但要按下面说的,固定咱们的版本与hash的话,就只能:
import { BaseAjax } from "https://cdn.skypack.dev/pin/jwfetch@v1.1.2-1LpCExuOCuNK2LPTj1mF/mode=imports/optimized/jwfetch.js";
这种状况又会有个问题,这只是一个js文件,并没有类型文件,怎么办?别慌,只须要加// @deno-types就行了:
// @deno-types='https://cdn.skypack.dev/-/jwfetch@v1.1.2-1LpCExuOCuNK2LPTj1mF/dist=es2019,mode=types/dist/index.d.ts'import { BaseAjax } from "https://cdn.skypack.dev/pin/jwfetch@v1.1.2-1LpCExuOCuNK2LPTj1mF/mode=imports/optimized/jwfetch.js";BaseAjax.defaults.baseURL = "https://api.github.com";console.log(BaseAjax);
总结
本文以AST为例,教你在应用deno进行开发的过程中,如何利用CDN来复用npm的node包。node.js曾经倒退了十余年,其中积攒了不可计数的资源,咱们要尽可能地复用它们,以晋升开发效率。