标签: vercel

  • 将 Next.js 项目从 Vercel 迁移到 Cloudflare

    将 Next.js 项目从 Vercel 迁移到 Cloudflare

    一起逃离 Vercel 拥抱 Cloudflare 吧

    Vercel 再次调价之后,性价比越来越低,每个月 $20 的额度根本扛不住什么访问量;而且建站所需的各种服务(数据库,KV 等)也欠缺,所以我觉得是时候迁离 Vercel,投奔赛博菩萨 Cloudflare 的怀抱了。

    不过由于 Cloudflare 平台的整体架构,其 Edge Runtime 和 Serverless runtime 都跟 Vercel,或者说标准架构存在一些不同之处,所以迁移的过程中往往需要我们做一些工作。本篇博客就来分享这些经验。

    Cloudflare 云服务

    首先,Cloudflare 不仅提供 Serverless / Edge 托管,更提供一整套几乎是必须的服务器组件:

    1. SQLite 接口的关系型数据库 D1,速度很快,第三方工具很多
    2. 形似 Redis 的 KV 数据库
    3. 存储服务 R2,兼容 AWS S3
    4. Queue、Durable Object 等几乎所有服务器长线运营必须的工具

    而且以上大部分都包含慷慨的免费额度,当你的产品度过极早期,需要更多额度时,$5/月也够用很久。总之,对比 Vercel 万国造且每个都要独立付费,当然是 Cloudflare 更好用。

    (当然,也会越来跟 Cloudflare 绑定越来越深,这方面见仁见智吧。)

    接下来,Cloudflare 更推荐我们使用他们家的 Worker 平台。以我的经验,使用 Worker 而不是 Pages 有以下好处:

    1. 实时日志,方便我们查看运行时错误和 debug
    2. 支持 cron trigger,可以方便的执行一些自动化操作
    3. 以及更好的缓存策略,比如预渲染

    自然,Worker 需要更多的工作,我们必须整体迁移到 OpenNext 才行。

    迁移到 OpenNext

    首先,请参考官方文档:https://opennext.js.org/cloudflare/get-started

    接下来,我也会捋一遍迁移过程,并分享我的经验。

    安装 @opennextjs/cloudflare

    这个适配器会帮我们在 Cloudflare 上运行我们的 Next.js 应用。

    pnpm install @opennextjs/cloudflare@latest

    安装 Wrangler

    Wrangler 是 Cloudflare 提供的命令行工具,可以帮我们完成很多工作,也是上面适配器的必备工具。

    pnpm install --save-dev wrangler@latest

    创建 wrangler 配置文件

    这个配置文件会影响到最后的部署和其它云服务使用。我建议大家使用 JSON 格式,因为语法更熟悉。

    {
      "$schema": "node_modules/wrangler/config-schema.json",
      "main": ".open-next/worker.js",
      "name": "<应用名称>",
      "compatibility_date": "<最近的日期>",
      "compatibility_flags": [
        "nodejs_compat",
        "global_fetch_strictly_public",
      ],
      "account_id": "<你的 account id>",
      "assets": {
        "directory": ".open-next/assets",
        "binding": "ASSETS",
      },
      "services": [
        {
          "binding": "WORKER_SELF_REFERENCE",
          "service": "<应用名称>",
        },
      ],
      "r2_buckets": [
        {
          "binding": "NEXT_INC_CACHE_R2_BUCKET",
          "bucket_name": "<BUCKET_NAME>",
        },
      ],
      "vars": {
        "NEXT_PUBLIC_SITE_URL": "<你的网站域名>"
      }
    }

    添加 open-next.config.ts 配置文件

    在根目录添加 open-next.config.ts 配置文件。

    import { defineCloudflareConfig } from "@opennextjs/cloudflare";
    import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
     
    export default defineCloudflareConfig({
      incrementalCache: r2IncrementalCache,
    });

    添加 .dev.vars 文件

    在根目录添加 .dev.vars 文件,告诉 Next.js 它应该使用哪一个 .env 文件。

    NEXTJS_ENV=development

    环境变量是比较难处理的一项工作。首先,线上使用的环境变量通常分两部分,一部分就是普通的变量,应该直接放在 wrangler.jsoncvars 字段里;另一部分是需要加密的比如各种 apiKey,需要通过 wrangler 工具放到 secrets 里。

    线上的环境变量必须保存在 wrangler.jsonc 里。这里我们只需要把本地开发环境所需的变量放在 .env.development,覆盖线上的即可。本地密钥也可以放在 .env 文件里。

    更新 package.json

    需要给 package.json 加上以下命令,方便开发和部署。

    "build": "next build",
    "preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
    "deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
    "upload": "opennextjs-cloudflare build && opennextjs-cloudflare upload",
    "cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts",

    其中,deploy 用来完成主动部署,upload 用来部署开发分支,cf-typegen 用来生成描述文件,让 IDE 的代码补全更强力。

    添加静态资源缓存

    创建 /public/_headers 文件,添加以下内容,让 Cloudflare CDN 默认缓存所有静态资源,加速网站访问。

    /_next/static/*
      Cache-Control: public,max-age=31536000,immutable

    移除 pages 相关内容

    从代码中移除 export const runtime = "edge";

    并卸载掉 @cloudflare/next-on-pages

    忽略掉 .open-next 和 .wrangler

    .gitignore 添加更多的忽略项。如果使用 ESLint,也可能需要添加。

    .open-next
    .next
    .wrangler

    本地开发

    修改 next.config.ts,增加 @opennextjs/cloudflare 提供的适配器。之后,你就可以使用 Cloudflare 提供的开发环境了。

    import type { NextConfig } from "next";
     
    const nextConfig: NextConfig = {
      /* config options here */
    };
     
    export default nextConfig;
     
    import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
    initOpenNextCloudflareForDev();

    【可选】移除首页的预渲染缓存

    如果你的首页需要加载远程数据,那么可能需要手动避免首页被预渲染,否则你可能会面对一个静态的首页。解决方案并不复杂,只需要给首页的 page.tsx 里添加下面的语句即可:

    // 完全不缓存,每次都重新渲染并加载
    export const dynamic = 'force-dynamic';
    // 或者如果不希望完全动态,只是希望数据不缓存
    // export const revalidate = 0;

    完成第一次部署

    接下来,建议大家执行 pnpm run deploy 完成第一次部署,这样会在 Cloudflare 里添加一个新的 worker,然后我们才好添加 secrets。

    关联 GitHub 仓库

    找到刚才创建的 Worker,在设置面板里找到“构建”,即可关联到我们的 GitHub 仓库。在构建配置里:

    1. 删除“构建命令”(Build command)
    2. 部署命令(Deploy comment)为 pnpm run deploy
    3. 非生产分支部署命令(Non-production branches deploy comment)为 pnpm run upload

    部署完成

    至此,迁移完成,后面正常推代码就可以触发自动部署了。

    总结

    其实还有一些工作要做,比如配置缓存,配置可见性,等等。大家可以根据需要来操作。

    希望这篇文章对大家所有帮助。如果大家对 Vercel,Cloudflare,Next.js 有任何问题或想法,欢迎留言讨论。

  • 【系列教程】使用 Vercel Serverless function 连接 APNs 实现 iOS 推送通知(2)代码解析

    【系列教程】使用 Vercel Serverless function 连接 APNs 实现 iOS 推送通知(2)代码解析

    上一篇文章我们分享了 Push Notification 的基础原理和项目配置,这一篇我们开始看具体的代码。

    (更多…)
  • 【系列教程】使用 Vercel Serverless function 连接 APNs 实现 iOS 推送通知(1)基础知识

    【系列教程】使用 Vercel Serverless function 连接 APNs 实现 iOS 推送通知(1)基础知识

    新年开新坑,写一个小教程,分享一下年前尝试用过 Vercel Serverlss function 通过 APNs 发送通知的经验,虽然能找到不错的教程,但仍然要踩一些坑。希望对大家有帮助。祝大家蛇年大吉,快速成长。

    (更多…)
  • 【代友招聘】【成都】Web3 教学网站 后端工程师

    【代友招聘】【成都】Web3 教学网站 后端工程师

    Hackquest.io 是我长期关注并辅佐的一家专注于 Web3 教学的网站的。他们由一群很有热情的年轻人组成,努力勤奋又有天赋,从创业至今取得了相当可观的成长。现在他们需要招聘一名 Node.js 后端工程师,需求大约如下:

    Node.js开发工程师

    「职责描述」

    • 负责有效的设计、开发和使用性测试。
    • 制定应用部署和基础架构维护的最佳策略。
    • 确保开发能够被有效低成本的迁移和部署。
    • 设置测试环境并提高开发准确率。
    • 优化数据库结构。

    「后端技术栈」

    • Node.js(核心),Nest.js(核心)
    • PostgresSQL, MySQL 等任意一种关系型数据库以及 Redis
    • 熟悉 Google Cloud 或其他 Cloud 相关服务,部署,数据库管理
    • TypeScript(核心)
    • 熟悉 Prisma

    「任职要求」

    • 工作及项目经验 3 年及以上
    • 大型项目经验优先
    • 具备扎实的数据结构和计算机系统基础,编码功底扎实,代码习惯优秀

    有兴趣、有能力的同学,请与我取得联系,我会推荐给他们进行进一步的面试。

  • 系列视频制作中:Next.js 全栈开发每日一签网站

    系列视频制作中:Next.js 全栈开发每日一签网站

    之前的几个系列基本都连载完毕。前些天开了一个新坑:全栈架构师系列。但是这个系列比较难录:讲得深,应用场景就窄,观众就少,像我这种发免费课的方式就比较亏;讲得浅,我觉得也没啥意思,担心将来大家一看,“就这?”。还有一点,技术难题不是每天都能遇到,要积累适合的话题,还要不担心泄漏技术秘密,其实比较难搞。所以只录了一期,因为第二期迟迟没想好怎么录,一直也没发。

    前阵子跟 201 老同事吃饭,了解到她也“毕业”了,正在小红书上创作“每日一签”,突然我觉得可以跟以前做的 拜拜 应用结合起来,搞个每日一签网站:

    1. 固定更新能提供 SEO 价值
    2. 拜佛和求签本身就是强关联的功能,可以把用户留住

    于是我们一拍即合,就有了 每日一签 这个网站。这个网站用到以下技术栈:

    1. 后台使用 Strapi 快速搭建,部署在 Zeabur 的 Docker 服务上
    2. 全栈开发使用 Next.js,App Router,全部 SSR,数据使用 Strapi RESTful API
    3. CSS 使用 TailwindCSS,并且基于 TailwindCSS 家的 Commit 模版二次开发
    4. 网站部署在 Vercel 上
    5. 数据库使用 TiDB Cloud Serverless (这次 TiDB Cloud 在我学习 Strapi 的过程中立了大功)
    6. 存储和 CDN 使用 Cloudflare R2
    7. 统计服务也用 Vercel

    这套技术栈完全免费,各种云服务的免费额度可以跑到一个很高的量。是我非常推荐的全栈技术栈,也是各种独立开发、出海创业的首选。所以从开始我就想把它做成一套全栈开发课程。正好可以作为之前几套全栈开发系列教程的补充:

    1. 基于 Next.js + React,便于大家学习和扩展技术栈
    2. 更复杂的网站,更丰富的功能
    3. 更复杂的数据结构和 API,但是更简单的后端处理
    4. 更全面的基础设施服务

    那么说干就干,我就一边开发一边制作视频。新的课程可能包含以下章节:

    1. 项目介绍,技术栈简介(视频制作中)
    2. 使用 Monorepo 管理复杂项目
    3. 使用 Docker 部署 Strapi 应用到 Zeabur (下周一 10-14 录制,正好填上欠 Zeabur 的推广)
    4. 使用 TiDB Cloud 提供数据库服务
    5. 使用 Cloudflare R2 提供存储和 CDN
    6. 使用 Next.js + Commit 模版开发网站
    7. 使用 Shadcn 组件库
    8. 添加每日页,制作 sitemap,提升 SEO
    9. 使用前端推送功能
    10. 使用 og 开发分享功能

    希望新的系列课程能帮助大家学会现代化的全栈开发,学会使用各种现代化的研发平台,给大家开展独立开发和技术出海带来新的机会。如果你对全栈开发、独立开发、技术出海感兴趣,请关注我的系列视频和博客更新。如果你对相关技术有疑问想寻求解答,欢迎留言。

  • 解决跨时区 Nuxt SSR 导致的页面离奇 Bug

    解决跨时区 Nuxt SSR 导致的页面离奇 Bug

    打开后台一看,如果本周再不写博客,就三周没更了,还是抽点时间分享点东西吧。今天结合近期解决的问题,分享一下出海服务全球用户,并且使用 SSR 时可能遇到的问题。

    问题

    我厂的 AI 日记产品 DailyLift 遇到一个非常奇怪的问题。合伙人发现,在午夜过后,打开我们的网页,界面会渲染得非常奇怪。

    这里的问题很多,不管是文字样式还是背景图案,都很奇怪,只看错误截图和代码完全没有思路。给不了解我厂产品的读者介绍一下上图中的 bug:

    1. No data 表示当天无数据,正常情况时字体很小。
    2. 只有具体的数字才应该显示成这么大的字体。
    3. 配图也不对,no data 对应的应该是其它图片。
    4. No data 自然不应该有弧形进度条。

    难以复现的 bug

    我们是远程工作,我一般会把工作时间固定在早上 9:30~晚上 6:30。当我次日开始工作,打开开发环境开始 debug,这个 bug 完全无法重现。对合伙人来说,这个 bug 也是时有时无。所以,这个 bug 在我们的任务列表里开了关关了开,反反复复,非常难搞。

    但是随着时间发展,我们还是总结了一些问题特征:

    1. 此问题只在午夜零点之后出现
    2. 此问题只在刚发布过日志之后出现(这个很关键,可惜我解决 bug 那天才发现)
    3. 此问题只在新加载页面时出现
    4. 此问题只在线上(生产 / 测试)环境中出现

    至此,我还是没有什么思路,只是觉得,可能要午夜的时候来调试一下。

    捕获 bug

    上上周,儿子考试结束,我们带他去长沙武汉各玩两天,逛街三天,赶车三次,日均 1w 步之后,我的膝盖很累。导致周三的力量举 PR 测试状态奇差,离既定目标差了一半。(感兴趣的同学可以看下:年中测试新极限,逛街三天赶车两次,状态很差,只完成目标的一边。下次继续努力吧

    晚上睡觉前,我心情比较低落,毕竟努力了半年,之前的运动表现估算起来,肯定不止这个数字。于是我就随手打开 DailyLift,写了篇日志。然后,我鬼使神差地想起这个 bug,随手刷新了一下页面,正所谓失之东隅,收之桑榆,竟然复现了这个 bug!

    简单介绍一下我们的技术选型:

    1. Nuxt
    2. Supabase
    3. 部署在 Vercel,非企业用户,只能选择特定区域,于是我们选择美西服务器

    开发环境无法复现,线上环境稳定复现。虽然表象无法推测问题所在,但也是巨大进步。我思来想去,突然想到,会不会跟服务器端渲染(SSR)有关?于是我查看源代码——注意,是源代码,不是 DOM 树;因为 DOM 树可能会被 Vue(Nuxt)修改过,不是初始状态——一看,果然,服务器端渲染的结果跟我页面的效果不一样。而这样的结果,是由于时区导致的。

    我的博客发表在 12 点之前,刷新页面在 12 点之后。如果大家观察上图,可以发现,我们是按照日期来分割数据的。我身处 +8 时区,所以我的 N 日 0 点,是 UTC N-1 日 16 点;Vercel 服务器位于美西,差不多是 -7 时区。于是,Vercel 在服务器端渲染页面的时候,他认为我的这篇日志,应该是 N-1 日 9 点钟写的,N-1 天还没结束,所以是当天(Today)的日志。 但是当我在本地运行 Vue 的时候,我已经是 N+1 日了,于是我本地的代码认为日志发表在昨天,今天还没写过日志。

    于是,Nuxt 尝试对 DOM 进行修改,但不知为何,它复用了服务器端传回来的部分 HTML,修改了部分 HTML,所以就出现了前面的 bug。

    解决 Bug

    找到问题根源之后,解决问题就没那么难了。唯一的难点就是克服测极限带来的身体疲劳,不过找到问题的兴奋感冲淡了这份疲劳。

    查阅文档之后我发现,Vercel 倒是早就帮我们准备了解决方案,我们只需要用useRequestHeader('x-vercel-ip-timezone') 就可以获取到用户所在的时区,接下来,只要保证整个 SSR 在这个时区里进行就好。

    我使用的 dayjs 来处理时间,它自带 timezone 功能,所以给所有 dayjs() 后面加上 dayjs().tz(tzHeader) 就可以。

    总结

    最后,困扰我们一个月之久的 Bug 终于解决。我也意识到处理时区在全球化应用开发时的重要性。合伙人问我有没有办法确保类似的问题不再发生,我回他:我这辈子都不会忘了处理时区了……

    希望这篇博客对你的出海应用开发有帮助。如果你对 Nuxt、服务器端渲染、云服务器等有问题,欢迎留言讨论。

  • 搬家记:从 Vercel 到 Cloudflare(Nuxt 项目x2)

    搬家记:从 Vercel 到 Cloudflare(Nuxt 项目x2)

    月底的时候,收到 Vercel 的邮件,提示我账号内有一些额度用量已经消耗 50%。我没在意,心想反正月底,马上不就归零了么?第二天起来越想越不对,我的 Vercel 是付费的 Pro 账号,计费周期是上月 22 日到本月 22 日,这才月底,才一周多,怎么会就用掉 50%?

    于是我回想起之前收到 Vercel 的邮件,说以后我每个月的费用会上升 30+美金,不由得背后一凛。赶紧上 Vercel 后台查看,发现 Vercel 开始用新的计费单位:Function Invocations。且 4 月 25 日起,新开通 Pro 的用户会使用这个方式计费;而 5 月 25 日(即上月底),我们这些老 Pro 用户也会采用这个方式计价。

    很明显,新计价单位比老的方式严苛很多,以至于我之前一半都用不掉的套餐费用,现在连半个月都撑不住。公平一点来说,我的项目都是 Nuxt,要走 Serverless Function,所以消耗可能比 Next.js 走 Edge Function 要高。但是,无论如何,这个价位都让我们动起了搬家的念头。目标毫无疑问,就是 Cloudflare。

    具体额度可能随时有变化,我就不在这里贴数字了,简单给大家划个标准:我在 Vercel 每月 $20 的额度,大约对齐 Cloudflare 的免费版;Cloudflare 每月 $5 的套餐额度,足够我 $50 Vercel + $5 Upstash,还有一大堆我没用起来的服务。

    单纯算经济帐,肯定是 Cloudflare 划算得多。但是 Vercel 行走江湖,靠的就是一手优秀的 DX,尤其在我搬家折腾完之后,更是这么觉得。整体过还比较顺利,但是坑也真没躲过去。接下来分享一些踩坑经历,希望对大家有帮助。

    第一步,创建项目。在 Cloudflare Pages 导入 Git 仓库即可,操作跟 Vercel 基本一致,无需详述。接下来,我们就有了部署在 xxx.pages.dev 子域名的网站,建议测试充分之后再切换域名。

    第二步,解决各种 [unenv] 问题。这个问题是由于 Cloudflare Worker 运行时精简(删掉)了一些 Node.js API 导致的。可能发生在各个环节,从部署到执行都有可能。我遇到的问题主要是:

    1. ioredis。因为我使用 Upstash Redis,所以直接换 @upstash/redis/cloudflare 然后使用 http endpoint 即可解决。两者的 API 有些许区别,不过功能性差异不大,替换起来不麻烦。
    2. Nitro Stroage。其实跟上面是一个问题,只不过表现不太一样。如果通过 nuxt.config.js 配置 Storage 使用 Redis,那么部署那一关都过不去……
    3. crypto.createHash。这个暂时没找到好办法,主要是 TiDB Serverless 最初使用 Digest 认证,所以我才必须使用。现在他们支持 Basic Auth 认证,所以我直接去掉对这个 API 的依赖就好了。

    第三步,安排 Cron job。这一步目前我也还没做好。Cloudflare Pages 不支持 Cron job,只能在 Workers 里安排 Cron Trigger。所以比较合理的做法是,建立一个统一的 cron worker,定时运行,粒度控制在比较合理的范围内,然后通过这个 worker 去调用分散在各个项目中的 cron job。

    于是,由于我们暂时无法离开 Vercel 的 Cron job,所以我们就还不能关掉 Vercel 上的项目。那么我们就必须开一个分支出来进行开发。好在 Cloudflare 可以支持指定特定分支作为 Production 的做法,所以这方面也没有问题。

    哦,对了,Pages 不支持在 wrangler.toml 里定义环境变量,以及我们在 Pages 里修改环境变量也不会触发重新部署,这点和 Worker 不一样,需要注意。

    最后,就是改变域名指向。我们必须在 Workers & Pages > 刚才的项目 > Custom Domains 配置自定义域名,仅在在 Websites > CDN 里配置是不够的,请大家注意。另外,由于 Nuxt 是 SSR 框架,所以我们必须关闭位于 Speed > Optimization > Content Optimization 的 “Auto Minify”,否则,可能会遇到重复的页面内容。

    还有一点,与 Vercel 不同,Cloudflare Pages 只包含 Edge 网络,并没有前面的 CDN 层。所以在 Cloudflare Pages 里增加缓存必须通过 Cloudflare CDN 来进行,同时 CDN 必须开启 Proxied,否则,原本在 Vercel 有效的缓存头就只能在浏览器里工作了。

    以及,Cloudflare Pages 没有提供页面重定向等功能,所以原本放在 Vercel.json 里的一些东西可能就要我们自己实现了。

    总结

    按惯例来总结一下。Cloudflare 的套餐性价比非常高,同样用量,价格可能 Vercel 的 1/10,还能覆盖其它服务。所以值得一试。但是问题也不少,比如运行时被进一步缩减、不支持 Cron job、没有 CDN 层、没有更高层级的 Headers 控制,等等,所以在使用时,体验可能还是略逊于 Vercel。尤其是迁移搬家,更要注意。

    好了,如果你对全栈开发,网站基础设施感兴趣,有问题有疑问,欢迎留言讨论。

  • 部署网站该选 Vercel 还是 Cloudflare Pages

    部署网站该选 Vercel 还是 Cloudflare Pages

    全栈开发者部署网站,首选无外乎 Vercel,Cloudflare Pages 二选一。那么,这两者间有何区别呢?结合我过去一年多的体验,简单分享一下。

    我目前两边都在付费使用,且都经历了一些团队协作。我觉得本次分享应该言之有物,不过如果跟事实有出入,欢迎各位指正。

    相似之处

    两者整体体验非常接近,都很好用。

    • GitHub 导入仓库
    • 新 commit 自动部署
    • 分支自动部署,预览新版本
    • 支持多种构建脚本
    • 免费域名(二级域名)
    • 免费永久 SSL 证书
    • CDN
    • 可观的免费额度

    Vercel 的优势

    1. 域名放在哪里都可以

    Cloudfare 最大的问题就是你非得把域名根 DNS 转过去,很蛋疼。虽然我对其他域名提供商也没什么忠诚可言,但是我就懒得换……

    经网友提醒,我又查看了一下,Cloudflare Pages 不需要停放根域名到 CF,所以这点二者一致。

    Vercel 这方面比较大度,你域名放在哪里都行,只要 CNAME 过来就能用。

    2. 集成数据服务非常方便

    Vercel 集成了很多数据服务,包括 config、KV、Storage、DB,使用起来非常方便,只需要在 GUI 上点一下,然后在本地把环境变量配置一下即可。使用的时候只需要安装指定依赖,非常好理解,和常规工作流程完全一致。

    CF 也有类似的服务,但是使用起来就麻烦很多。他们家只针对自家 Worker 做了比较简单的集成,想在自己熟悉的框架里使用会比较麻烦。

    3. 团队管理更好用

    虽然 Vercel 团队需要花钱($20/人月,相当贵),但是团队管理很好用,该有的功能都有,权限配置好,用起来也很顺畅。

    CF 则不然,我到现在都没找到控制团队权限的做法,导致我无法方便的将统计报表分享给朋友。

    4. 更好的 Serverless 支持

    Next.js 本来就是 Vercel 主力开发的,所以自然,Next.js 在 Vercel 上可以放心使用,服务器环境绝对不会成为问题。默认情况下,Vercel 会使用 Edge 引擎提供更好的性能和更低廉的价格;实在不行,也可以切换到 Serverless 模式获得更好的兼容性。

    CF 只支持 node.js 的子集(相当于 Vercel Edge Function),所以如果我们的业务代码中使用的函数库包含了一些不被支持的功能,就无法使用 CF 了。

    Cloudflare Pages 的优势

    1. 提供很好用的分析工具,包括 Web Vitals

    我其实到现在都无法难理解,这东西在 Vercel 那边居然要付费使用,还得通过代码嵌入页面。

    CF Pages 这边用起来很简单。直接打开开关,它会负责把统计代码插入页面,然后我们就能看到包含访问量、来源、技术等的数据统计。更重要的是,我们还能看到 Web Vitals 数据,而 Web Vitals 数据,能直接影响 SEO,所以这个统计就非常有帮助了。

    2. 免费额度更高

    这点 Vercel 也很值得吐槽,它们家额度设计相当诡异。比如,类似(1)的访问量统计,一个月额度 25k,啥意思呢?你的网站访问量超过每天 800,这个月可能就要交钱了……我完全无法理解他们的设计思路。

    还有 KV 也是,明明是集成的 Upstash 服务,Upstash 每天免费 10K,它们家免费 5K……其它带宽、容量等就不细说了,都不敢放开用。

    CF 具体多少我没仔细看,不过印象里要多得多得多,可能是最大方的云服务商了,基本属于 $20/月 放开用。

    3. 全球最近接入

    这点说实话我不太敢确定,没有具体测过。按照官方文档的说法,Vercel 企业版是全球的,但是免费和团队版都要手动选择边缘计算服务器的部署位置。

    CF 按照后台的说法,会自动选择离用户最近的地方执行函数功能,我们就当他是全球最近接入吧。

    4. 目前 *.pages.dev 没有被墙

    这意味着即使你没有自己的域名,可以用 Cloudflare Pages 提供服务。相对来说,*.vercel.app 已经被墙的很彻底。

    不过,如果真的是持久运营的产品,还是早点切换到自己的域名吧。

    排除的其它选项

    • VPS:太麻烦了,我已经不想再自己折腾服务器了。
    • GitHub Pages:不支持边缘计算,纯静态限制太多。
    • Supabase:Deno 限制太多。

    总结

    我个人的感受:Vercel 强在开发体验(DX);CF Pages 强在量大管饱。具体怎么选择,还请大家酌情考虑。

    如果你对出海开发、全栈开发、云服务提供商有什么想法、问题和分享,欢迎留言讨论。祝大家清明安康。

  • SSR,云平台,ChatGPT——我的 2023 技术关键词

    SSR,云平台,ChatGPT——我的 2023 技术关键词

    前言

    2023 年,因为换工作,启动新项目等原因,我对我的技术栈进行了比较大的更新,主要集中在这三个方向:

    1. SSR(Server Side Rendering,服务器端渲染)。之前我开发的项目基本上都是 SPA(Single Page Application),比如 Vue,但之后我会越来越多开始用 Nuxt。由于基础设施的发展,以后 SSR 会更方便更好用。
    2. 云平台。以前我大概买了 3、4 台云服务器用来做各种尝试,在上面各种折腾。去年使用 Vercel、Supabase、CloudFlare 平台之后,我已经不打算再在服务器上浪费时间了,云平台实在太好用了。未来我会努力把所有服务都迁移到云平台上,新增产品都直接云原生。
    3. ChatGPT。相信不只是我,很多人都会把 ChatGPT 作为去年技术的首选关键词。如今我不仅在上面完成产品开发,日常也会使用它替代大部分的搜索;甚至我家孩子写作业也会使用它来帮忙。我认为,未来 ChatGPT 就像是搜索引擎一样,决定了一个人的起点和成长速度。

    接下来逐个分享。

    服务器端渲染,SSR

    起初我不是很看重 SSR,我总觉得,我当年也写过 PHP,有什么“服务器端渲染”我没见过?实际用过之后,我承认:真香……

    首先,使用 SSR 可以提升用户体验,且有利于 SEO,这点相信大家都知道。如果对其原理不太清楚的话,欢迎观看我的视频:从浏览器渲染机制理解 Web 性能——“在浏览器地址栏输入 URL,按下回车后会发生什么?”

    其次,如今的 SSR 与当年 PHP 模版套页面的实现有很大区别:

    1. 语言同构化:开发难度大大降低,没有心智负担。
    2. 数据传递与状态管理:虽然数据不能完全通用,但是框架尽量会帮我们处理好,让我们在服务器端和客户端都能自由使用。
    3. 渲染由边缘计算负责:这一点有点依赖云平台,不过考虑到浏览器的渲染机制,SSR 并不会拖慢渲染速度,用户体验只会更好。
    4. 页面切换不需要重新加载。对于旧的编程语言来说,因为前后端环境割裂,所以页面切换的时候都是重新加载完整页面;但是新框架下,则只需要加载数据即可,此处跟 SPA 的体验无二。

    第三,如今的 SSR 框架都很好的整合了服务器,包括中间件等功能,还有各种官方第三方模块支持,能大大降低我们开发服务器软件的成本。所以已经是我启动新项目的不二之选。

    云平台

    以前我长期维护好几台服务器,一方面可以部署自己做的产品 demo,另一方面也可以部署一些开源项目方便日常使用。因为各种云都有面向新用户的优惠活动,所以成本不高,我觉得值得一搞。

    自己的服务器当然比较比较自由,坏处就是免不了产生运维成本,即使使用 docker 也一样。部署新代码至少要去跑一遍拉取脚本,对吧?我的一位老板朋友甚至请我帮忙写了一套服务器脚本,用来做 CI/CD。

    初期这么搞没问题,但后来就越来越觉得功能不够,性价比也太低,开始寻求替代方案。之前我参加 Hackathon 的时候了解到 Vercel 云平台。它与 GitHub Pages 不同,支持 SSR、支持云函数,配合一些云数据库,比如 Upstash,可以快速搭建起来一套可用的服务。去年年初,我的那位老板朋友想做一套打分系统,放在他的静态网站里,于是,我就尝试用 Nuxt.js + Upstash 开发了一套,并且部署在 Vercel 上,效果非常好,免运维,多环境,推到 GitHub 自动部署,实在太好用。

    我把这个过程制作成了系列课程:Nuxt3+Vercel+Serverless 数据库全栈开发。大家感兴趣不妨看一看。

    后面一发不可收拾,过去一年我不再采购新的单体服务器,旧的服务器用完也不再续费。新产品都部署在 Vercel 等云平台上面,帮我节省了大量的时间。

    Vercel 去年年中的时候开通了存储功能,实际上就是打包了几家云数据库服务来卖,我也很快获准开通。从此,云平台使用就更加顺利了。临近年底,我尝试 CloudFlare Pages,效果也非常好。他们家的优势是自带统计分析功能,远比 Vercel 大方,一站式解决更省心。

    云数据库方面,我使用 Upstash 的 Redis,KV 数据库足以满足大部分产品需求。数据库用 Supabase 和 TiDB 比较多。前者支持 PG Vector,方便我们进行 LLM Embedding & Search;后者则提供 5GB 免费额度,比较好用。云存储有 CF 的 R2,空间和流量也相当充足。如果不是 PHP 太老没人支持,我都想把博客这台机器退掉了。

    ChatGPT,以及其它

    ChatGPT 更是值得大书特书的一个技术关键词。不过考虑到大家去年一整年应该已经被类似的内容淹没了,所以我这里就少写一些,只说说我的情况。

    我目前订阅了 ChatGPT+,方法是借用国外亲戚的手机号注册,并且用他的手机号注册 PayPal,通过 Google Play 订阅。订阅的原因是 ChatGPT 4 + DALL-E 都可以随便用,比 API 便宜得多。

    在编程领域,GPT-4 比 GPT-3.5 好太多了,知识库更新到去年 4 月份之后,除了 next.js 14 的内容外,我日常的编程问题大多可以用 GPT-4 解决,比如:

    • 写正则
    • 写 SQL
    • 查函数、查第三方库
    • 纠正函数错误

    帮我节省了大量的 Google 时间,单凭这点,每月 $19.99 的订阅费用就很值得。

    除此之外,我还在继续使用 GitHub Copilot。Copilot 也很好用,除了生成工具函数、编写测试外,我发现翻译语言和框架方面也有很大的作用。去年我就完全靠它开发了一个 flutter 应用,方法就是把 TS+Vue 写好的代码丢给它让它翻译。

    所以,无论是学习新东西,保障日常开发,还是扩展新领域,AI 对我都帮助巨大。

    总结

    总而言之,如果再有同学问,前端想学后端,应用学什么语言框架以及是否需要搭自己的服务器?我都会建议他们:不要学 Express、Koa;习惯用 Vue 就学 Nuxt,习惯用 React 就学 Next.js;不需要搭建服务器,就用云存储就能解决绝大多数问题。

    我还建议大家,尽快想办法开通 ChatGPT,再不济国产大模型也要用起来,未来是 AI 的时代,学会用 AI,效率会大幅度提升。半年的初入门新人,善用 AI 可以赶上 3 年的老程序员;而老程序员学会用 AI 之后,可以快速把自己的能力扩展到其它领域。

    以上,就是我去年关键的技术栈总结,希望对大家有所帮助。如果大家有什么意见建议,想说的想聊的,欢迎留言。

  • 【视频】Nuxt3+Vercel+Serverless 全栈开发(5):部署到 Vercel+开发统计功能

    【视频】Nuxt3+Vercel+Serverless 全栈开发(5):部署到 Vercel+开发统计功能

    课程继续。仍然结合近期的开发经验,分享最近我比较喜欢的全栈+高效+免费+云原生技术方案。

    https://www.bilibili.com/video/BV16h411N762/ (请 B 站有号的同学帮忙点赞)

    本次课程内容:

    • 将作品部署到 Vercel
    • 使用自定义域名保障国内访问
    • 开发统计功能页面

    终于讲到部署环节了。其实 Vercel 对现代化 Web 全栈开发是非常重要的组成部分,它自带的 Serverless 功能是实现服务器端渲染(SSR)的关键,而且我们也需要使用 Serverless 来完成数据交互。部署到 Vercel 非常简单,点几下就能完成。

    Vercel 官方网站 vercel.com 在中国大陆可以无障碍访问,但是免费提供的二级域名 *.vercel.app 不行。解决方案很简单,自己注册一个域名,然后 CNAME 过去即可。注册域名的选项很多,各大云平台如阿里云、腾讯云均可。自己的小域名如果不提供大规模服务,不备案也可以用。价格大概一年十几块吧。

    然后讲解制作统计页面,主要涉及 Redis 的操作和前后端数据交互。之前埋下的数据结构设计,在此可以更好的演示。

    至此,这个系列基本连载完成。从技术选型、到项目搭建、到前后端开发、到最终部署上线,都覆盖到了。其它想讲的内容还有很多,不过都属于锦上添花,对于有开发经验的同学来说,相信现在已经可以动手。未来当然会继续深入,把统计功能加强一些,把关系型数据库也纳入进来。进阶课也在规划中,比如面对内容更庞大的网站,这个项目中太过简单的数据交互、缓存处理、SEO 都不够用,需要进阶强化。敬请期待吧。

    本周正好端午节,休息一周,周三(6月21日)晚上直播答疑,欢迎围观。


    这期视频也剪得很细,还做了字幕,希望大家能学到东西。

    如果你有任何问题、建议,欢迎留言讨论。请 b 站有号的同学帮忙分享完播一键三连,谢谢大家。

    另外,我也在 YouTube 上上传了一份,大家有空的话,麻烦帮忙关注下我的油管频道,感谢感谢。肉山全栈小课堂 – YouTube