Serverless 部署 Deno 应用有那么难吗 ???

举报
胡琦 发表于 2021/02/10 11:59:19 2021/02/10
【摘要】 Copy攻城狮在线解答:Serverless 部署 Deno 应用,So easy!

Serverless 部署 Deno 应用有那么难吗 ???

Deno 是一个简单、现代且安全的 JavaScript 和 TypeScript 运行时环境,其基于 V8 引擎并采用 Rust 编程语言构建。Deno 自打出生就不乏话题:“Node.js 的替代品,将来可能就不需要 Node.js 了”、"Deno 并不是下一代 Node.js"、“Deno 已经死了吗?”……而对于 Copy 攻城狮 来说,有趣就行!目前 CloudBase Framework 支持一键部署 Deno 应用,而我却踩了不少坑,谨以此文纪念逝去的那些一文不值的时光!

CloudBase Framework

云开发 CloudBase 是某云的热门产品,云开发应用可以是运行在云开发环境的应用,例如一个包含前后端、数据库等能力的服务,可以通过一键部署,直接部署在云开发环境中,使用云开发底层的各项 Serverless 资源,享受弹性免运维的优势。 什么是云开发?什么是 Serverless?Copy 攻城狮心中满是疑问,还能不能愉快地切图!上一次了解到云开发还是看到“小程序·云开发”,印象比较深刻的是云开发提供一个云函数环境,提供云数据库、鉴权服务等,无需自备服务器搭建后端服务。 听过一些老师的课,得益于云开发,前端开发尤其是小程序开发者,一个人就能前后端甚至运维也全干,快速上线一款弹性伸缩企业级应用;而 Serverles功能即服务(Function-as-a-Service,缩写为 FaaS) 和 平台即服务(platform as a service,缩写:PaaS 的组合,是当前主流的技术实现;不过,Copy 攻城狮只会跑跑 Hello World 。在 Serverless 技术体系中,我们熟知的 Node.js 扮演着举足轻重的一环,比如 Serverless FrameworkVercel等 Serverless 优秀产品都离不开 Node.js 完善的生态。 CloudBase Framework也是如此,因此我们能够轻而易举的想到 CloudBase Framework 的安装和使用方式。

  • 安装 CLI 工具

    npm install -g @cloudbase/cli@latest

    如遇到权限问题,请使用 sudo , MacOS 上好像容易出现。

  • help 指令

    cloudbase -h

    盲猜应遵循了国际惯例, help help help!,当然,惊喜发现 cloudbase 还能简写为 tcb

     Tip: cloudbase 命令可以简写为 tcb

    CloudBase CLI 1.5.0
    CloudBase Framework 1.6.18-+

      命令

        login           [options]                  登录腾讯云账号
        logout                                     登出腾讯云账号
        env             [cmd]                      环境管理操作
        fn              [cmd]                      操作函数
        framework       [cmd]                      云开发 Serverless 应用框架操作
        hosting         [cmd]                      静态托管资源管理操作
        new             [appName] [template]       创建新的云开发应用
        open            [link]                     在浏览器中打开云开发相关连接
        storage         [cmd]                      云存储资源管理操作
        service         [cmd]                      HTTP 访问服务管理操作

      选项

        --verbose                                  打印出内部运行信息
        -r, --region <region>                      指定环境地域
        --mode <mode>                              指定加载 env 文件的环境
        --config-file <path>                       指定配置文件路径
        -v, --version                              输出当前版本
        -h, --help                                 查看命令帮助信息

      Tips:

        – 登录

          $ tcb login

        – 创建新的云开发应用

          $ tcb new appName

        – 部署云函数

          $ tcb fn deploy

        – 查看命令使用介绍

          $ tcb fn -h

  • 登录

    看到有登录的命令,先尝试一下,由于我之前已经登录过了,通过 logout 登出,再 login 。

    huqi@Mac-mini deno % tcb login
     CloudBase CLI 1.5.0
     CloudBase Framework 1.6.18
     ✔ 您已登录,无需再次登录!
    huqi@Mac-mini deno % tcb logout
     CloudBase CLI 1.5.0
     CloudBase Framework 1.6.18
     ✔ 注销登录成功!
    huqi@Mac-mini deno % tcb login
     CloudBase CLI 1.5.0
     CloudBase Framework 1.6.18
     ⠋ 获取授权中...

    此时,会通过默认浏览器打开一个 CLI 授权的页面,这让我想起 Huawei DevEcho Studio 在登录时也会调用网页来进行授权。登录逻辑实现的代码,我们可以给 github 加 1s 来打开在线 VSCode 来查看:https://github1s.com/TencentCloudBase/cloudbase-cli/blob/HEAD/src/commands/account/login.ts,感兴趣的小伙伴可以尝试通读源码。

    授权成功之后,它还会征求我的意见收集我的使用数据,为了更好的体验 Cloudbase ,我愿意!我愿意奉献我的使用数据!

    async function askForCollectDataConfirm({
        const agree = await usageStore.get('agreeCollect')
        if (agree) return
        // 询问
        const { confirm } = await inquirer.prompt({
            type'confirm',
            name'confirm',
            message'是否同意 Cloudbase CLI 收集您的使用数据以改进产品?',
            defaulttrue
        })

        if (confirm) {
            await usageStore.set('agreeCollect'true)
        }

        await collectAgree(confirm)
    }
  • 初始化项目及部署

    既然前边已经提到可以使用简写tcb来代替那串冗长的字母,那肯定使用tcb来创建初始化项目。

    tcb new deno_hello deno    # 以 deno 为模板创建项目
    cd deno_hello
    tcb                        # 部署项目

    非常简单明了的命令就实现了一个 Deno 应用的 Serverless 部署。当然,也正是三行命令,让我踩了一个又一个的坑,为此还花费了我好几毛钱的”巨款”,钱不钱倒是无所谓,主要是磨洋工都快把我耐心耗尽了!

    先来看看tcb new deno_hello deno干了啥,大胆猜测是创建了deno_hello文件夹,并通过调用https://tcli.service.tcloudbase.com/download传入 os、uin、macMd5、templateId、templateName、version 等参数,获取到 deno 模板并写入到deno_hello项目中。

    Cloudbase deno 模板源码依旧可通过给 github 加 1s 来查看:https://github1s.com/TencentCloudBase/cloudbase-templates/tree/master/deno。如果您碰巧留意到cloudbaserc.json,您可能会想为啥 deno 版本是 1.6.3 呢?:

      {
      "version""2.0",
      "envId""{{envId}}",
      "$schema""https://framework-1258016615.tcloudbaseapp.com/schema/latest.json",
      "framework": {
        "name""deno-app",
        "plugins": {
          "deno": {
            "use""@cloudbase/framework-plugin-deno",
            "inputs": {
              "dockerImage""debian:latest",
              "runtime""1.6.3"
            }
          }
        }
      }
    }

    对,这里便是我踩的坑!目前来看,在执行tcb之前,去掉"runtime": "1.6.3"这行使用 deno 最新的版本能避坑!

Deno 镜像之“锅”

很荣幸能遇到 Deno 生态建设崎岖之路的“bug”,云里雾里,这究竟是怎样一个故事?请听 Copy 攻城狮娓娓道来。

大概半个月之前,我尝试使用 Cloudbase 部署 deno 的 HelloWorld 应用,拉的 Cloudbase 官方的模板直接部署,怎么都不成功,部署失败的关键日志提示如下:

CloudBase CLI 1.2.7
CloudBase Framework 1.6.11
……
step 4/14 : RUN curl -fsSL https://x.deno.js.cn/install.sh | sh
---> Running in df11b9868b9a
�[91m#=#=#
curl: (22) The requested URL returned error: 403
�[0mThe command '/bin/sh -c curl -fsSL https://x.deno.js.cn/install.sh | sh' returned a non-zero code: 22

当时看到https://x.deno.js.cn/install.sh就想到了 justjavac 大大的 Deno 镜像,不过没想到的居然是jsdelivr CDN 单文件最大只支持 20M导致了 Deno 1.7.0 版本在当时的镜像无法正常使用,因为 1.7.0 版本的 zip 包刚好超过了 20M,参见https://github.com/justjavac/dvm/issues/42

这间接导致了 Cloudbase 中 Deno 模板使用最新的版本时,通过镜像无法下载;也造就了我这个注定是巧合的坑!

好在 justjavac 大大及时修复了这个“bug”:

fn compose_url_to_exec(version: &Version) -> String {
  if version.major >= 1 && version.minor >= 7 {
    format!("https://dl.deno.land/release/v{}/{}", version, ARCHIVE_NAME)
  } else {
    format!(
      "https://cdn.jsdelivr.net/gh/justjavac/deno_releases/{}/{}",
      version, ARCHIVE_NAME
    )
  }
}

当然,社区也有大佬折腾出了"自给自足"的方法--向 Deno 学习优秀的脚本管理,果真是自己动手丰衣足食。

这就结束了?非也非也,Deno 的生态目前还不够强大,同样是版本升级带来的问题,这回轮到了 denon

Denon 兼容之“锅”

Denon 之于 Deno 如同 Nodemon 之于 Node.js ;Denon 可以监视您的 Deno 应用程序中的所有更改并自动重新启动,避免了每修改一处代码就要手动重启的繁琐;此外,对于 Deno 应用来说,还提供了体验非常棒的配置。

在我们通过tcb new deno_hello deno拉取的模板中,也能看到 Denon 的身影,denon.yml:

scripts:
  lint: deno fmt --check .
  build:
    cmd: mkdir dist && deno bundle --no-check src/entry.ts dist/entry.js
    watch: false
  start:
    cmd: deno run --no-check dist/entry.js
    env:
      PATHNAME: "/deno-app"
    allow:
      - net
      - env
      - read
  dev:
    cmd: deno run --no-check src/entry.ts
    env:
      PORT: "3000"
    allow:
      - net
      - env
      - read

上边这个配置文件将我们可以做的一些事安排得明明白白:代码检查、打包构建、本地调试等。

那 Denon 带来了什么困扰呢?“罪魁祸首”还是因为 Deno 版本升级。当时,Deno 刚升到 1.7.0 ,使用 Denon 就会报错permission error,参见:fix: permission error on latest deno:

TS2339 [ERROR]: Property 'url' does not exist on type 'NetPermissionDescriptor'.
? `--allow-${pd.name}=${pd.url}`
                                           ~~~
at https://deno.land/std@0.83.0/permissions/mod.ts:18:44

当时普遍认为 Deno 1.6.3 是比较稳定的版本,至少也不会导致 Denon 无法正常使用,我猜大概也是因为这个原因,我们在上文中提到 Cloudbase 中 deno 模板目前也是使用的 1.6.3。

出现类似的“锅”,如果您依旧想使用最新版本,那就只能等等兼容问题被处理,或者您亲自动手处理兼容问题。 再回过头来看看这个兼容问题是如何处理的?看上去只是改了一个版本号,但究竟为何要这样改,估计只能深入 Deno 源码学习才能一探究竟了。

牛刀小试

既然所有的问题都如愿以偿地被社区大佬们解决了,那接下来,我还是想试试 Cloudbase 和 Deno 这两把“牛刀”,完成我琢磨了很久的一个 Hello World,姑且称为一条热搜。主要是不想浪费之前通过 Deno 获取的每日热搜数据,加上想体验一下 Cloudbase 的一键部署功能,难得 Cloudbase 支持 Deno 插件。

按照剧情,上文中初始化话 Deno 项目之后,直接输出 tcb 这三个字母就能进行部署,请尽量本地调试好应用再部署,每次部署都会,当然,截止文章发布前,建议去到指定 Deno 版本的这行配置:

- "runtime": "1.6.3"

简单修改了一下 HelloWorld 的代码,让它变成一个我想要的一条热搜,数据基于trending-in-one,我粗暴地在 controller 中获取热搜数据:

    const response = await fetch(`https://cdn.jsdelivr.net/gh/hu-qi/trending-in-one/raw/toutiao-search/${formatTime(new Date(),{template:'{{YYYY}}-{{MM}}-{{DD}}'})}.json`)
    const responseJson = await response.json()
    const index = Math.floor(Math.random() * responseJson.length);

    const pathname = Deno.env.get("PATHNAME") || '';
    ctx.response.body = await renderFile(`${Deno.cwd()}/views/home.ejs`, {
      title'一条热搜',
      text: responseJson[index],
      pathname,
    });

来看看部署之后惨不忍睹的效果:

在线预览地址:http://deno-demo-3ghgaf7pa8d97b90-1253880795.ap-shanghai.app.tcloudbase.com/ (PS:如果无法访问,那一定是我欠下巨款跑路了,您可以自行一键部署)

一键部署:

最后唠嗑一下 Cloudbase 的一键部署,一键部署按钮可以让公开的 Git 项目一键部署到云开发 CloudBase 上,大大简化用户部署的门槛,便用户快速使用和体验应用。一键部署功能支持 Github,Gitlab,Coding,Gitee 等 Git 仓库地址。 简直是 Copy 攻城狮的福音,复制粘贴都不用了,一键部署!(PS: 其实还是需要手动进行配置)

一键部署按钮的生成可以访问:https://docs.cloudbase.net/framework/deploy-button.html,只需填入仓库地址、目录和分支,这点和 Vercel 部署也有些类同:

总体体验还是不错的,不过最后还是遇到了一个访问地址的坑,还没来得及填,不过影响不大。大概是一键部署成功之后,访问地址*.ap-shanghai.app.tcloudbase.com/deno-app在浏览器中打开时变成了文件下载,而实际服务的地址是没有deno-app这个服务名称路径的,大概率是我的配置有点偏差,弃坑弃坑!

小结

总得来说,随着 Deno 生态的不断完善,Serverless 部署 Deno 应用变得越来越简单。借助云开发 Cloudbase,您无需关注 Deno 的安装实现、服务的运维等等,还能以最低的成本运行 Deno 应用。希望我的踩坑能够给您启发,请多多指教,感谢!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。