wangpin34 / blog

个人博客, 博文写在 Issues 里
5 stars 0 forks source link

2021/08/13: Deno 好不好用 ? #72

Open github-actions[bot] opened 3 years ago

github-actions[bot] commented 3 years ago

封面

brad-pearson-hv-sKLb6kXU-unsplash

Photo by Brad Pearson on Unsplash

本周主题:Deno 好不好用?

本来打算更新下 ChromeBook 作为开发机器的内容,但是发现没什么干货:锅主要在于 ChromeBook,谁让它的 Linux Beta 那么好用, Vscode,Android Studio 安装如此丝滑,简直就是另一个版本的 MacOS,除了显示器渣一点。

所以,还是聊聊别的吧。刚好玩了一会 Denodownload

其实听说 Deno 很久了,据说,是 NodeJS 的创始人另开炉灶,研发了一套 native 支持 es6 和 TypeScript 的 runtime。我自己大部分工作都要碰到这两个东西,babel 说实话已经很方便了,不需要怎么折腾就能跑起来。但是 native 支持还是很有吸引力,因为三个原因。

所以对于依赖 es6 和 TypeScript 的开发人员来说,Deno 是很有吸引力的。

但它还不够完美。我最终停下了打算用 Deno 重构一个项目的脚步,因为,Deno 不能直接使用 NPM package。stackoverflow 上这个答案介绍了一些曲线救国的方式,How to use npm module in DENO? 。且不考虑这些方法是否足够稳定,已有项目做这样的改造必然涉及到 code change,是一个没有回头路的做法,而强迫用户必须在 NodeJS 和 Deno 中做选择的后果就是,很多用户可能因此打消了使用 Deno 的念头。我就是其中一个。让我加很多配置文件让原本 NodeJS驱动的项目变成 Deno 驱动,可以;让我改项目源代码,对不起,这个风险太大了。

一个号称 NodeJS 超集的 Language 竟然「胆敢」对 NPM 说 No,我也在不知道该怎么评价这种行为。傲慢?愚蠢?还是背后有星辰大海般的理想。但不管如何,重构是显然不太可能了。

不过,用来写写小脚本应该还是可以的,新项目,没有历史包袱,也可以尝试。毕竟,三个好处摆在面前,还是挺诱人的。

读书

《哈利波特与阿兹卡班的囚徒》 《象与骑象人》

我发现一个很有趣的现象,虽然我留下了很多评论(不是书评,而是划线评论),但是收到点赞或者评论总是来自金庸武侠系列丛书。点赞的就不用说了,肯定是觉得说得多说得好了。评论的就很分化了,有的觉得我道出了金庸没有点出来的一面,有的觉得我曲解了金庸的意思。比如最典型的,我认为金庸并没有将令狐冲写的很完美,真实情况是令狐冲这个角色很不完美,很有问题,甚至可以苛刻的评价为幼稚,肤浅,领导力也渣的要命。而反对我这种观点的评论很多。

另外,我的书单「武林群豪录」截止目前为止有 64 人收藏。

我倒不想评价这些反对本身,我觉得,很有意思的事情是:

本质原因在于金庸的刻意为之,毕竟,这些书当初可是连载《明报》的,更多争议角色或者情节意味着更有话题性,更多关注更多订阅。结果证明金庸是很成功的。多次翻拍,改编,演绎,原著热度不减,就是明证。

我关注过的好几个网红作者,球评作者,他们也都是资深金庸迷,原著读过10次 +,以此为基础重新演绎的文章不计其数。

也许从文学性上来说,金书(金庸武侠,请允许我用这个简称)并不那么伟大。但是从流传度上讲,过去的几十年,很少有书籍能像金书这样持续的热度。我之前因为金书本身的立意,对它的评价并不高,但是立意这种东西是有时代局限性的,我现在看不上的东西,只能说它落后于这个时代了可能,但它的故事性,叙述节奏,人物刻画,还是有很多精妙的地方,值得反复玩味的。

健身

体重:- 0.0

经过两个星期断续的跳绳(隔天深蹲哑铃取代跳绳),耐力变好了一点,于是调整了 Timer 配置,将每组训练间隔由 1 分钟缩减为半分钟。我现在使用的 Timer 是 Timer Plus。UI 简洁,很好上手,强烈推荐。

WechatIMG106

周四尝试了一下开合跳,感觉比单纯跳绳的强度还要大一点,我感觉可以在 12 组跳绳训练里替换两组为开合跳。

App

N/A

编程

完成了一个简单的 Todo app,目的主要是练习 coredataCRUD。顺便玩了 Swipe Action,就是滑动手势触发动作。

extension TodosViewController {
    override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

        let item = items[indexPath.row]

        let doneAction = UIContextualAction(style: .normal, title: "Done") { (action, view, bool) in
            item.finished_at = Date()
            self.updateItem(item)
        }
        doneAction.backgroundColor = UIColor.green

        return UISwipeActionsConfiguration(actions: [doneAction])
    }
}

storeboard 的 outlet 和 action 有一点点理解了,outlet 就是组件的 ref,action 就是组件的各种 listener。但是 navigation 组件的 segue 和 action 还是挺绕的,segue 要搭配什么 func 才能工作,没有系统的认识。下周应该要多读读基础文档了。之前玩 flutter 的时候,flutter 的 navigation 很接近 web 的 html5 history。这样看来,web 转 flutter 当然更容易。

我用 child_process 的 spawn 调用 create-react-app,起初发现无法准确的捕捉结束信号。我是这样实现的:

const  cp = spawn('npx', ['create-react-app', process.argv[2]])
await new Promise((resolve, reject) => {
      cp.stdout?.on('data', (data) => {
        //print
      })
      cp.stderr?.on('data', (err) => {
        reject(err)
      })

      cp.on('close', (code) => {
        resolve(code)
      })
})

我在 stderr 中 reject,可是 reject 发生之后,child process 并没有停止,还在继续执行。

问题出在哪里呢?stderr 有数据,不就是结束了吗?

不是的,想错了。

难道出现 err 了不是停止吗?嘿,还真不是。

stderr 表示的标准错误流,这个有数据代表什么呢?代表 npx 或者 create-react-app 往错误流里面写数据了。

console.error(err)

如果你直接在命令行使用 create-react-app,也许也能看到出现一些错误或者警告。这些错误信息并没有导致严重的失败,错误输出之后,create-react-app 继续进行,最后 init 完成。所以,stderr 有数据并不是错误并且结束的信号,只是错误的信号,而错误并不一定导致结束。准确的结束信号还是 close 事件,也就是。

 cp.on('close', (code) => {
    resolve(code)
 })

而如果要区分成功结束和失败终止,应该检测 code 的数值,一般来说,按照linux 的传统,0 代表成功,1代表失败。所以:

 cp.on('close', (code) => {
    if (code == 0) {
       resolve()
    } else {
       reject()
     }
 })