<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title><![CDATA[程序员三隐]]></title> 
<atom:link href="https://www.hackpro.tech/rss.php" rel="self" type="application/rss+xml" />
<description><![CDATA[使用emlog搭建的站点]]></description>
<link>https://www.hackpro.tech/</link>
<language>zh-cn</language>
<generator>emlog</generator>

<item>
    <title>我为什么又认真看了一遍 n8n：从 GitHub Trending 自动追踪到博客自动发布</title>
    <link>https://www.hackpro.tech/?post=11</link>
    <description><![CDATA[<h1>我为什么又认真看了一遍 n8n：从 GitHub Trending 自动追踪到博客自动发布</h1>
<p>最近看到一篇讲 n8n 的文章，我又把这类自动化工作流工具重新认真看了一遍。原因很简单：这两年大家都在聊 AI Agent、自动化、工作流，但真正能落地的方案，最后还是要回到“怎么把信息抓进来、怎么处理、怎么发布出去”这种很具体的链路上。</p>
<p>而 n8n 之所以一直被反复提起，不只是因为它火，而是它确实站在一个很实用的位置：<strong>足够可视化，足够灵活，也足够接近真实业务场景。</strong></p>
<blockquote>
<p>原文来源：<a href="https://zhuanlan.zhihu.com/p/1920982802221991385">https://zhuanlan.zhihu.com/p/1920982802221991385</a><br />
项目地址：<a href="https://github.com/n8n-io/n8n">https://github.com/n8n-io/n8n</a></p>
</blockquote>
<p><img src="https://picx.zhimg.com/v2-5b050eaee93d7ffa38b906bda36ac8a2_720w.jpg?source=172ae18b" alt="" /></p>
<h2>n8n 到底适合什么人？</h2>
<p>如果只是看一句定义，n8n 是一个开源工作流自动化工具。但这个定义太平了，不足以说明它为什么值得关注。</p>
<p>我的理解是，n8n 最适合下面这几类人：</p>
<ul>
<li>想把重复性流程自动化的开发者</li>
<li>想接 API、接数据库、接第三方服务，但又不想自己从零写一套调度系统的人</li>
<li>已经开始尝试用大模型做内容处理、摘要、路由、通知的人</li>
<li>希望把“采集 → 清洗 → 判断 → 生成 → 发布”串成完整链路的人</li>
</ul>
<p>它和很多“自动化平台”最大的区别，不只是节点多，而是它允许你在<strong>低代码和可编程之间自由切换</strong>。简单的流程可以拖拽，复杂的逻辑可以直接塞代码节点，这个平衡点其实挺关键。</p>
<h2>这篇文章里，最有价值的不是介绍，而是那个实际案例</h2>
<p>原文用了一个很接地气的例子：</p>
<p><strong>自动追踪 GitHub Trending 项目，并进一步做 AI 总结，再推送到邮件或博客。</strong></p>
<p>这个案例比“发个通知”“同步个表单”更有代表性，因为它已经接近一条真正有价值的内容生产链路了。拆开来看，大概是这样：</p>
<ol>
<li>定时抓取 GitHub Trending 列表</li>
<li>将项目基础信息存入数据库（文中用的是 Supabase）</li>
<li>过滤掉已经处理过的项目</li>
<li>拉取项目 README 等核心内容</li>
<li>用 LLM 做总结和重写</li>
<li>自动发邮件或发布到博客系统</li>
<li>记录已发布状态，避免重复推送</li>
</ol>
<p><img src="https://pic1.zhimg.com/v2-dd261a2d091d8b8fb8348f912f4c86e2_1440w.jpg" alt="" /></p>
<p>这件事看起来不复杂，但其实已经把一个自动化系统的关键能力都串起来了：</p>
<ul>
<li><strong>定时触发</strong></li>
<li><strong>数据存储</strong></li>
<li><strong>状态去重</strong></li>
<li><strong>外部 API 调用</strong></li>
<li><strong>大模型处理</strong></li>
<li><strong>多渠道分发</strong></li>
</ul>
<p>如果一个工具能把这几件事比较顺地组合起来，它基本就不只是“玩具”了。</p>
<h2>我觉得 n8n 最值得看的地方</h2>
<h3>1. 它不是只给“不会写代码的人”准备的</h3>
<p>很多人一看可视化工作流，就会默认这是给非技术人员用的。但 n8n 真正有意思的地方，是它并没有把开发者挡在门外。</p>
<p>你既可以用现成节点去连 GitHub、Supabase、Webhook、邮件服务，也可以在代码节点里直接写 JavaScript 或 Python，把一些不规则的处理逻辑自己兜住。</p>
<p>这意味着它不是在替代开发，而是在替代<strong>那些重复、分散、胶水化的开发工作</strong>。</p>
<h3>2. 开源和自托管，意味着边界更可控</h3>
<p>这类系统一旦接入内部数据、业务通知、私有服务，大家最担心的通常不是“能不能用”，而是：</p>
<ul>
<li>数据放在哪里</li>
<li>能不能自己部署</li>
<li>能不能按自己的规则改</li>
<li>后续会不会被平台能力限制住</li>
</ul>
<p>n8n 的开源和自托管能力，给了它一个很现实的优势：<strong>你不一定非要把工作流托管在别人的平台上。</strong></p>
<p>对很多团队来说，这不只是技术偏好，而是合规、成本和可维护性的考虑。</p>
<h3>3. 它很适合做 AI 时代的“胶水层”</h3>
<p>现在很多 AI 应用最大的问题不是模型不够强，而是上下游没接起来。</p>
<p>模型会总结、会分类、会抽取、会改写，但如果它前面接不到稳定数据源，后面接不上数据库、通知系统、发布系统，那结果就是 demo 很惊艳，落地很费劲。</p>
<p>n8n 恰好能补上这层：</p>
<ul>
<li>前面接数据源</li>
<li>中间做规则和路由</li>
<li>把模型插进流程中间</li>
<li>后面接发布、归档、通知</li>
</ul>
<p><img src="https://pic2.zhimg.com/v2-1a34b90dd72911d7dff6ce1c3618b84f_1440w.jpg" alt="" /></p>
<p>从这个角度看，n8n 不只是自动化工具，也很像是 AI 工作流的基础设施之一。</p>
<h2>这篇案例给我的几个实际启发</h2>
<h3>用数据库记状态，比“纯流程编排”更重要</h3>
<p>原文里用 Supabase 存储 Trending 项目列表和已推送列表，这一点我很认同。</p>
<p>很多人刚开始做自动化时，容易把重点放在节点怎么连、提示词怎么写，但真正跑起来后最容易出问题的，其实是：</p>
<ul>
<li>哪些数据已经处理过</li>
<li>哪些结果已经发过</li>
<li>哪些任务失败了需要重试</li>
<li>哪些内容需要二次更新</li>
</ul>
<p>如果没有状态层，自动化流程就很容易变成一次性演示。加上数据库之后，才更像一个能长期运行的系统。</p>
<h3>不是所有 API 都要等官方节点</h3>
<p>文章里提到 GitHub 原生节点不支持直接获取 README，于是用 HTTP Request 节点自己调接口。这其实非常符合实际。</p>
<p>自动化平台真正好不好用，不在于“有没有 1000 个官方节点”，而在于当没有现成节点时，你能不能顺畅地自己补上去。</p>
<p>n8n 这里的思路是对的：</p>
<ul>
<li>有现成节点就直接接</li>
<li>没有就用 HTTP Request 自定义</li>
<li>再配合表达式和代码节点做转换</li>
</ul>
<p>这样灵活性就出来了。</p>
<h3>AI 总结不是终点，发布链路才是</h3>
<p>很多人现在做 AI 工作流，做到“模型输出了一段还不错的总结”就结束了。但对真正想提高效率的人来说，这一步只是中间环节。</p>
<p>真正的闭环应该是：</p>
<ul>
<li>内容抓取</li>
<li>信息筛选</li>
<li>AI 处理</li>
<li>人工审核（可选）</li>
<li>自动分发</li>
<li>发布归档</li>
</ul>
<p><img src="https://pic1.zhimg.com/v2-bc3ebde15433f55e2f345c104d013632_1440w.jpg" alt="" /></p>
<p>原文把邮件发送和博客发布都纳入了工作流里，这比单纯做一个“AI 摘要 demo”更有价值，因为它已经在替代真实工作流中的一部分劳动了。</p>
<h2>如果你也想用 n8n，我建议先从这类场景开始</h2>
<p>与其一上来就做很大的 Agent 系统，不如先做一些小而完整的自动化闭环。比如：</p>
<ul>
<li>每天抓取几个固定信息源，做摘要后发到飞书/邮件</li>
<li>监控 GitHub、RSS、论坛或社交平台的关键词变化</li>
<li>收集表单、工单或用户反馈后自动分类入库</li>
<li>从数据库里挑选内容，自动生成周报、日报、候选选题</li>
<li>把 AI 输出结果自动同步到博客、知识库或内部文档系统</li>
</ul>
<p>这些事情的共同点是：</p>
<ul>
<li>规则相对明确</li>
<li>上下游接口清晰</li>
<li>自动化收益很直接</li>
<li>即使模型偶尔不稳定，也可以靠人工兜底</li>
</ul>
<h2>n8n 的边界也要看清楚</h2>
<p>当然，我并不觉得 n8n 是“万能解法”。</p>
<p>至少有几个边界要意识到：</p>
<ul>
<li>如果业务逻辑极其复杂，最终还是要回到代码系统本身</li>
<li>如果任务量特别大、并发很高，工作流平台未必是最优承载层</li>
<li>如果你对工程化、版本管理、测试、可观测性要求很高，就得认真设计而不是一路堆节点</li>
<li>如果把所有判断都丢给 LLM，流程会变得不稳定，维护成本也会升高</li>
</ul>
<p>所以更适合的思路是：<strong>把 n8n 当成编排层，而不是试图让它吞掉整个系统。</strong></p>
<h2>写在最后</h2>
<p>我一直觉得，真正好用的自动化工具，不是让你“看起来像在搭系统”，而是它真的能把一段原本反复发生的工作，从手工变成稳定运行的流程。</p>
<p>n8n 之所以值得持续关注，就是因为它已经不只是“拖拽几个节点发通知”这么简单了。尤其在 AI 能力逐渐成为流程中间件的一部分之后，它这种能连数据、连模型、连发布渠道的工具，会越来越有现实价值。</p>
<p>如果你最近也在折腾：</p>
<ul>
<li>GitHub 信息追踪</li>
<li>AI 自动摘要</li>
<li>自动写周报/日报</li>
<li>内容自动发布</li>
<li>数据采集到分发的完整链路</li>
</ul>
<p>那 n8n 确实值得你亲自上手跑一遍。</p>
<p><img src="https://picx.zhimg.com/v2-a6a797d0a5a33a152803f0ad194ba3d7_1440w.jpg" alt="" /></p>
<hr />
<h2>额外放两张我从桌面随机翻到的图</h2>
<p>你让我“在桌面上随机找几张图作为配图”，我顺手也挑了两张放在文章尾部，当成一个轻量的视觉收尾。它们和 n8n 本身没有直接对应关系，更像是博客排版上的补充。</p>
<p>（这里原本放了两张桌面随机配图，我先移除了，避免出现失效图片。）</p>
<hr />
<p><strong>原始参考</strong></p>
<ul>
<li>知乎原文：<a href="https://zhuanlan.zhihu.com/p/1920982802221991385">https://zhuanlan.zhihu.com/p/1920982802221991385</a></li>
<li>n8n GitHub：<a href="https://github.com/n8n-io/n8n">https://github.com/n8n-io/n8n</a></li>
<li>n8n 文档：<a href="https://docs.n8n.io/">https://docs.n8n.io/</a></li>
</ul>
<p><strong>标签建议：</strong> n8n, 自动化, AI工作流, GitHub, 效率工具</p>]]></description>
    <pubDate>Sun, 05 Apr 2026 01:37:07 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://www.hackpro.tech/?post=11</guid>
</item>
<item>
    <title>我试了下最近很火的 web-access：它不是普通联网插件，而是一套高权限网页操作思路</title>
    <link>https://www.hackpro.tech/?post=9</link>
    <description><![CDATA[<p>最近我顺手把一个叫 <strong>web-access</strong> 的 Skill 装到了 OpenClaw 里，来源是这个 GitHub 仓库：</p>
<blockquote>
<p><a href="https://github.com/eze-is/web-access">https://github.com/eze-is/web-access</a></p>
</blockquote>
<p>第一眼看上去，它像是一个“增强联网能力”的 Skill，但真看完它的 README、SKILL.md 和几段核心脚本后，我觉得它更准确的定位应该是：<strong>一套给 Agent 用的网页访问策略 + 浏览器控制通道 + 站点经验机制</strong>。</p>
<p>它不是简单补一个搜索工具，而是试图回答一个更大的问题：<strong>当 Agent 需要上网时，到底应该用什么方式获取信息，什么时候该读静态页面，什么时候该直接接管浏览器。</strong></p>
<h2>它到底是什么？</h2>
<p>从仓库介绍来看，web-access 想补上的主要是三块：</p>
<ul>
<li>联网工具选择策略</li>
<li>通过 CDP 连接真实 Chrome 的浏览器操作能力</li>
<li>对特定网站的经验积累与复用</li>
</ul>
<p>仓库里对它的描述也很直接：原本只有 WebSearch、WebFetch 这类能力还不够，真正麻烦的场景其实是登录态、动态渲染、页面交互、社交平台抓取和复杂网页流程。web-access 的野心，就是把这些都纳入一套统一方法里。</p>
<h2>我觉得它最有意思的地方</h2>
<h3>1. 它不是单一工具，而是“调度策略”</h3>
<p>我觉得这项目最聪明的一点，不在于多写了几个脚本，而在于它把“怎么联网”抽象成了一套判断逻辑。</p>
<p>在它的 Skill 说明里，大致是这么分流的：</p>
<ul>
<li>只是做搜索发现：用 WebSearch</li>
<li>已知 URL，要抽正文：用 WebFetch</li>
<li>需要原始 HTML：用 curl</li>
<li>页面动态渲染、需要登录态、要点按钮或上传文件：直接走浏览器 CDP</li>
</ul>
<p>这件事听起来很朴素，但对 Agent 很重要。很多时候不是“能不能上网”，而是“<strong>该用哪条通道上网才最靠谱</strong>”。</p>
<h3>2. 它试图直接接入你平时用的 Chrome</h3>
<p>这个设计很强，也很危险。</p>
<p>web-access 的核心脚本会：</p>
<ul>
<li>检查 Node.js 环境</li>
<li>检查 Chrome 是否开启 remote debugging</li>
<li>自动发现调试端口</li>
<li>启动本地 CDP Proxy</li>
<li>通过 WebSocket 连接到你当前正在使用的 Chrome</li>
</ul>
<p>一旦连上，它就能通过本地 HTTP API 去做很多事情，比如：</p>
<ul>
<li>新建 tab</li>
<li>导航页面</li>
<li>在页面里执行 JS</li>
<li>点击按钮</li>
<li>模拟真实鼠标点击</li>
<li>上传文件</li>
<li>页面截图</li>
<li>读取页面信息</li>
<li>关闭自己开的 tab</li>
</ul>
<p>换句话说，它不是“帮 Agent 看网页”，而是真的在给 Agent 一只可以操作浏览器的手。</p>
<h3>3. 它默认把“已登录状态”当成能力来源</h3>
<p>这也是它和很多普通网页工具最不一样的地方。</p>
<p>它不是拉起一个隔离浏览器，而是尽量复用你日常使用中的 Chrome，因此天然继承登录态。对一些必须登录才能读内容、必须在网页里点击才能完成的任务来说，这当然很方便。</p>
<p>但反过来说，这也意味着权限边界会变得很模糊：</p>
<ul>
<li>如果你的 Chrome 里登着 GitHub、飞书、后台系统、社交平台</li>
<li>那么这个 Skill 在合适条件下就可能访问这些页面</li>
<li>甚至执行交互操作，而不仅仅是读取内容</li>
</ul>
<p>这类能力，实用性很高，但一定不该被当成“普通搜索增强”。</p>
<h2>它适合什么场景？</h2>
<p>我觉得 web-access 真正适合的是这些任务：</p>
<ul>
<li>需要登录之后才能访问的网页</li>
<li>动态渲染严重、普通抓取拿不到内容的页面</li>
<li>必须点击、滚动、上传、截图才能完成的流程</li>
<li>某些社交平台或后台系统的自动化操作</li>
<li>多个网页目标并行调研</li>
</ul>
<p>特别是它提到的“并行分治”，思路其实挺对路：把多个互不依赖的网页任务分发给多个子 Agent，各自开 tab、各自处理、最后回收摘要。这比把所有抓取内容都塞进一个上下文里要干净很多。</p>
<h2>它的问题也很明显</h2>
<h3>1. 权限太高</h3>
<p>它的 README 和 Skill 文档写得很清楚：很多联网任务都应该优先纳入它的处理逻辑。问题是，一旦一个 Skill 试图接管“所有联网”，它就不再只是一个增强插件，而更像一个高权限入口。</p>
<p>简单说：</p>
<ul>
<li>它能连浏览器</li>
<li>浏览器里有登录态</li>
<li>登录态背后是真实账户</li>
</ul>
<p>这三件事叠在一起，就决定了它必须谨慎使用。</p>
<h3>2. 它很容易和现有工具重叠</h3>
<p>如果你本来已经有这些能力：</p>
<ul>
<li>普通网页搜索</li>
<li>网页正文提取</li>
<li>独立浏览器自动化</li>
</ul>
<p>那 web-access 的价值更多是在“<strong>复用真实 Chrome 登录态</strong>”这一点，而不是替代一切。</p>
<p>如果只是公开网页、普通文章、一般信息检索，其实没必要每次都把任务升级到真实浏览器层。</p>
<h3>3. 社交平台自动化有现实风险</h3>
<p>仓库里也提到了像小红书这类平台的操作，并明确提示了风控风险。这个提醒我觉得是对的。凡是涉及平台自动化，技术上能做，不代表账号层面没有代价。</p>
<h2>我会怎么用它</h2>
<p>如果是我自己的工作流，我会把 web-access 视作一个<strong>高权限模式</strong>，而不是默认模式。</p>
<p>我大概会这么分：</p>
<h3>先用轻工具的场景</h3>
<ul>
<li>查资料</li>
<li>搜公开网页</li>
<li>读博客正文</li>
<li>拉取文档内容</li>
</ul>
<p>这类事情，轻量工具就够了。</p>
<h3>只有满足这些条件时，才启用 web-access</h3>
<ul>
<li>必须依赖我当前 Chrome 的登录态</li>
<li>页面必须通过真实交互才能推进</li>
<li>目标站点对静态抓取很不友好</li>
<li>我要做的是“操作网页”，不是“读取网页”</li>
</ul>
<p>也就是说，它不是“默认通道”，而是“必要时启用的特权通道”。</p>
<h2>最后</h2>
<p>我觉得 web-access 是个很有想法的项目。</p>
<p>它真正值得看的一点，不是又多了几个抓网页的命令，而是它在试图把 <strong>Agent 联网这件事从“工具堆叠”推进到“策略层设计”</strong>。这一步其实挺关键。很多 Agent 工具都在补功能，但很少有人认真处理“什么时候该用哪种能力”这个问题。</p>
<p>但也正因为它不是普通 Skill，而是一个可能直接接入你真实浏览器、真实账户状态的高权限方案，所以它的正确使用方式绝对不是“装上就把所有联网都交给它”。</p>
<p>我会继续关注这个项目，但前提是：<strong>把它放在该放的位置——强力、有效，但需要节制。</strong></p>
<hr />
<p>来源：</p>
<ul>
<li>GitHub 仓库：<a href="https://github.com/eze-is/web-access">https://github.com/eze-is/web-access</a></li>
<li>仓库说明中提到的公众号文章：<a href="https://mp.weixin.qq.com/s/rps5YVB6TchT9npAaIWKCw">https://mp.weixin.qq.com/s/rps5YVB6TchT9npAaIWKCw</a></li>
</ul>]]></description>
    <pubDate>Thu, 02 Apr 2026 21:33:30 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://www.hackpro.tech/?post=9</guid>
</item>
<item>
    <title>Docker 部署 OpenClaw 最新版实战：从端口映射到 Control UI 配对全流程排查</title>
    <link>https://www.hackpro.tech/?post=8</link>
    <description><![CDATA[<h1>Docker 部署 OpenClaw 最新版实战：从端口映射到 Control UI 配对全流程排查</h1>
<blockquote>
<p>这次我的目标很直接：在 Docker 中部署最新版 OpenClaw，并让 Mac 本地浏览器通过 <code>http://localhost:8888</code> 访问容器中的 OpenClaw 控制界面。看起来只是一个简单的端口映射问题，实际排查下来，涉及 Docker 端口发布、服务绑定地址、Control UI 的 Origin 校验，以及浏览器设备配对四个层面。</p>
</blockquote>
<h2>背景</h2>
<p>我希望实现下面这条访问链路：</p>
<pre><code class="language-text">Mac 浏览器
  -&gt; http://localhost:8888
  -&gt; Docker 端口映射 8888:18789
  -&gt; 容器内 OpenClaw 监听 18789
  -&gt; OpenClaw Control UI / Gateway</code></pre>
<p>一开始以为只要把 Docker 参数写成 <code>-p 8888:18789</code> 就够了，但实际情况比这复杂一些。好在这次完整走通之后，整个路径反而变得很清晰：</p>
<ol>
<li>先让容器真正跑起来</li>
<li>再让宿主机能访问到容器内服务</li>
<li>再让浏览器来源通过 Control UI 的安全检查</li>
<li>最后完成浏览器设备配对</li>
</ol>
<h2>一、先用 Docker 启动最新版 OpenClaw</h2>
<p>机器里已经有 OpenClaw 的最新镜像，因此第一步不是重新构建，而是直接用现成镜像启动容器。</p>
<p>我最终使用的是这种方式：</p>
<pre><code class="language-bash">docker rm -f claw

docker run -d \
  --name claw \
  -p 8888:18789 \
  dr34m/openclaw:latest \
  openclaw gateway --allow-unconfigured</code></pre>
<p>这里最关键的是：</p>
<ul>
<li><code>8888</code> 是 <strong>Mac 宿主机端口</strong></li>
<li><code>18789</code> 是 <strong>容器内 OpenClaw Gateway 端口</strong></li>
</ul>
<p>也就是说，我想要的是：</p>
<ul>
<li>浏览器打开 <code>http://localhost:8888</code></li>
<li>Docker 把请求转发到容器内的 <code>18789</code></li>
</ul>
<p>到这一步，Docker 层的端口映射已经满足目标了。</p>
<h2>二、为什么端口映射对了，页面还是打不开？</h2>
<p>最初最容易误判的是：既然已经 <code>-p 8888:18789</code> 了，那打不开一定是 Docker 端口没映射好。</p>
<p>但继续排查后发现，问题不在 Docker 本身，而在 OpenClaw 服务监听地址。</p>
<h3>1. 宿主机端口其实已经被 Docker 占住了</h3>
<p>从 Docker 状态能看到类似信息：</p>
<pre><code class="language-text">0.0.0.0:8888-&gt;18789/tcp</code></pre>
<p>这说明 Docker 已经在宿主机上监听了 8888。</p>
<h3>2. 但访问 <code>localhost:8888</code> 仍然失败</h3>
<p>这时访问健康检查会看到 connection reset 一类错误，表面上像是服务没起来。</p>
<h3>3. 真正原因：OpenClaw 只绑定在容器内部 loopback</h3>
<p>继续看容器日志，发现关键信息是：</p>
<pre><code class="language-text">[gateway] listening on ws://127.0.0.1:18789</code></pre>
<p>这就意味着：</p>
<ul>
<li>OpenClaw 进程是活着的</li>
<li>它确实监听在 18789</li>
<li>但它只监听 <strong>容器内部的 <code>127.0.0.1</code></strong></li>
<li>Docker 虽然把宿主机的流量转发到了容器，但服务本身只接受容器 loopback 访问</li>
</ul>
<p>这也是为什么：</p>
<ul>
<li>容器里测 <code>127.0.0.1:18789</code> 是通的</li>
<li>宿主机测 <code>127.0.0.1:8888</code> 却不通</li>
</ul>
<p>本质上不是“端口映射失败”，而是“服务没有对容器网络开放”。</p>
<h2>三、把 OpenClaw 的绑定地址改成 <code>lan</code></h2>
<p>OpenClaw 的 Docker 文档里提到，Docker 场景下不要让 Gateway 只绑定在 loopback，而应该使用 <code>lan</code>。</p>
<h3>1. 配置文件位置</h3>
<p>这次修改的是容器内部的配置文件：</p>
<pre><code class="language-text">/home/node/.openclaw/openclaw.json</code></pre>
<h3>2. 需要增加的配置</h3>
<pre><code class="language-json">{
  "gateway": {
    "bind": "lan",
    "mode": "local"
  }
}</code></pre>
<h3>3. 两个配置项分别做什么</h3>
<h4><code>gateway.bind = "lan"</code></h4>
<p>这是这次修复里最核心的一步。</p>
<p>它的作用是让 OpenClaw 从只监听容器内部 loopback，变成监听对容器网络可达的地址。</p>
<p>修改前，日志里是：</p>
<pre><code class="language-text">ws://127.0.0.1:18789</code></pre>
<p>修改后，日志变成：</p>
<pre><code class="language-text">ws://0.0.0.0:18789</code></pre>
<p>也就是说服务从“只在容器内部自言自语”，变成了“容器网络里的请求也能进来”。</p>
<h4><code>gateway.mode = "local"</code></h4>
<p>这个配置主要是为了让 Docker / 本地场景下的 Gateway 行为更稳定，避免后续 Control UI、CLI 或配对时把目标地址理解错。</p>
<p>可以把它看作一个配套项：</p>
<ul>
<li><code>bind</code> 解决“服务能不能被外部打到”</li>
<li><code>mode</code> 让“本地部署语义”保持一致</li>
</ul>
<h3>4. 改完后重启容器</h3>
<pre><code class="language-bash">docker restart claw</code></pre>
<h3>5. 验证结果</h3>
<p>这时再访问：</p>
<pre><code class="language-bash">curl http://127.0.0.1:8888/healthz</code></pre>
<p>已经能返回：</p>
<pre><code class="language-json">{"ok":true,"status":"live"}</code></pre>
<p>说明：</p>
<ul>
<li>Docker 端口映射正常</li>
<li>OpenClaw 监听地址也已经正确</li>
<li>Mac 宿主机终于能真正打到容器内服务</li>
</ul>
<h2>四、页面能打开了，但又报 <code>origin not allowed</code></h2>
<p>到这里，静态页面已经能打开，但并不代表 Control UI 已经能和 Gateway 建立控制连接。</p>
<p>此时浏览器会提示类似：</p>
<pre><code class="language-text">origin not allowed
(open the Control UI from the gateway host or allow it in gateway.controlUi.allowedOrigins)</code></pre>
<h3>1. 这是什么问题？</h3>
<p>这不是端口问题，而是 <strong>Control UI 的来源校验（Origin 校验）</strong>。</p>
<p>我这次是通过：</p>
<ul>
<li><code>http://localhost:8888</code></li>
</ul>
<p>打开页面的。</p>
<p>于是浏览器在建立 WebSocket / 控制连接时，会带上 Origin：</p>
<ul>
<li><code>http://localhost:8888</code></li>
</ul>
<p>但 OpenClaw 当前配置里并没有明确允许这个来源，于是连接被拒绝。</p>
<h3>2. 解决方法</h3>
<p>继续修改同一个配置文件：</p>
<pre><code class="language-text">/home/node/.openclaw/openclaw.json</code></pre>
<p>加入：</p>
<pre><code class="language-json">{
  "gateway": {
    "bind": "lan",
    "mode": "local",
    "controlUi": {
      "allowedOrigins": [
        "http://localhost:8888",
        "http://127.0.0.1:8888"
      ]
    }
  }
}</code></pre>
<h3>3. 为什么要写两个 Origin</h3>
<p>因为访问本地服务时，实际浏览器来源可能有两种常见形式：</p>
<ul>
<li><code>http://localhost:8888</code></li>
<li><code>http://127.0.0.1:8888</code></li>
</ul>
<p>两个都加进去，能避免后续切换地址时再踩一次坑。</p>
<p>如果你未来打算通过局域网 IP 访问，比如：</p>
<ul>
<li><code>http://192.168.x.x:8888</code></li>
</ul>
<p>那也需要把对应的 Origin 再补进去。</p>
<h2>五、Origin 通过了，但又提示 <code>pairing required</code></h2>
<p>这一步也很有代表性。</p>
<p>很多时候看到 <code>pairing required</code> 会以为服务还是坏的，其实恰恰相反：</p>
<ul>
<li>端口已经通了</li>
<li>Origin 校验也已经过了</li>
<li>浏览器已经开始真正接触 Gateway 了</li>
<li>只是当前浏览器设备还没有被信任</li>
</ul>
<p>换句话说，这是一个 <strong>安全配对问题</strong>，不是网络问题。</p>
<h3>1. <code>pairing required</code> 的含义</h3>
<p>OpenClaw 不会默认信任所有能打开页面的浏览器设备。Control UI 和 Gateway 建立控制连接前，需要这个浏览器设备先完成配对授权。</p>
<h3>2. 这一步怎么做</h3>
<p>要做三件事：</p>
<ol>
<li>列出待配对设备</li>
<li>找到当前浏览器对应的 requestId</li>
<li>批准这个请求</li>
</ol>
<p>因为这次不是通过 Docker Compose，而是单容器 <code>docker run</code> 启动的，所以我直接在容器里调用 OpenClaw CLI。</p>
<h3>3. 先获取 token，再查看待配对设备</h3>
<p>OpenClaw Gateway 当前是 token 鉴权，所以 CLI 连接 Gateway 时必须显式带 token。</p>
<p>查看待配对设备的思路是：</p>
<pre><code class="language-bash">openclaw devices list --url ws://127.0.0.1:18789 --token &lt;token&gt;</code></pre>
<p>这时能看到一个 Pending 请求。</p>
<h3>4. 批准该浏览器设备</h3>
<p>拿到 requestId 后，执行：</p>
<pre><code class="language-bash">openclaw devices approve &lt;requestId&gt; --url ws://127.0.0.1:18789 --token &lt;token&gt;</code></pre>
<p>批准成功后，再次查看设备列表，就会从 Pending 变成 Paired。</p>
<p>此时浏览器刷新页面，就可以真正进入 Control UI。</p>
<h2>六、这次到底改了哪些地方？</h2>
<p>如果把整个过程压缩成最关键的几个改动，其实就是下面这些。</p>
<h3>1. Docker 启动方式</h3>
<pre><code class="language-bash">docker run -d \
  --name claw \
  -p 8888:18789 \
  dr34m/openclaw:latest \
  openclaw gateway --allow-unconfigured</code></pre>
<h3>2. 容器内配置文件</h3>
<pre><code class="language-text">/home/node/.openclaw/openclaw.json</code></pre>
<h3>3. 最终关键配置</h3>
<pre><code class="language-json">{
  "gateway": {
    "auth": {
      "mode": "token",
      "token": "..."
    },
    "bind": "lan",
    "mode": "local",
    "controlUi": {
      "allowedOrigins": [
        "http://localhost:8888",
        "http://127.0.0.1:8888"
      ]
    }
  }
}</code></pre>
<h3>4. 设备配对</h3>
<ul>
<li>列出待配对设备</li>
<li>找到 requestId</li>
<li>手动 approve</li>
</ul>
<h2>七、这次排查真正解决的是哪四层问题？</h2>
<p>这次最值得记住的一点是：<strong>浏览器能不能打开一个 Docker 里的 OpenClaw，不是只有端口映射这一层。</strong></p>
<p>实际上需要依次打通四层：</p>
<h3>第 1 层：Docker 端口映射</h3>
<pre><code class="language-text">8888 -&gt; 18789</code></pre>
<p>这是入口，但只是入口。</p>
<h3>第 2 层：OpenClaw 的监听地址</h3>
<p>如果服务只监听 <code>127.0.0.1</code>，那 Docker 端口映射再对也没用。</p>
<p>要改成：</p>
<pre><code class="language-json">"gateway": {
  "bind": "lan"
}</code></pre>
<h3>第 3 层：Control UI 的 Origin 白名单</h3>
<p>页面资源能打开，不等于 Control UI 可以连接 Gateway。</p>
<p>要允许：</p>
<pre><code class="language-json">"allowedOrigins": [
  "http://localhost:8888",
  "http://127.0.0.1:8888"
]</code></pre>
<h3>第 4 层：浏览器设备配对</h3>
<p>即使前面都没问题，浏览器设备依然可能因为没被批准而卡在：</p>
<pre><code class="language-text">pairing required</code></pre>
<p>需要手动批准当前浏览器设备。</p>
<h2>八、我的结论</h2>
<p>这次看起来只是“把 Docker 端口从 18789 换成 8888”，但真实工作量其实在排查路径上。</p>
<p>如果只看 Docker 参数，很容易以为问题已经解决；但实际还要一路确认：</p>
<ul>
<li>服务到底有没有起来</li>
<li>它监听的是不是对外可达地址</li>
<li>Control UI 有没有允许当前浏览器 Origin</li>
<li>这个浏览器设备有没有完成配对</li>
</ul>
<p>真正跑通之后，思路反而非常清楚：</p>
<blockquote>
<p>端口映射解决“流量能不能到容器门口”，绑定地址解决“服务接不接这个流量”，Origin 白名单解决“Control UI 认不认这个页面来源”，设备配对解决“Gateway 信不信这个浏览器”。</p>
</blockquote>
<p>把这四层都打通之后，<code>http://localhost:8888</code> 才真正变成一个可用的 OpenClaw 控制入口。</p>
<h2>写在最后</h2>
<p>这次部署虽然绕了一点，但也顺手把 OpenClaw 在 Docker 场景下的关键连接链路梳理清楚了。对后面做长期部署、改成 <code>docker compose</code>、补充模型 provider 配置，都会轻松很多。</p>
<p>如果后续要把它变成长期可维护的方案，我更推荐继续往两个方向走：</p>
<ol>
<li>把当前运行参数固化成 <code>docker-compose.yml</code></li>
<li>补齐模型 provider / API key / 持久化配置</li>
</ol>
<p>这样它就不只是“页面能打开”，而是一个真正可长期使用的 Docker 版 OpenClaw 环境。</p>]]></description>
    <pubDate>Wed, 01 Apr 2026 11:38:02 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://www.hackpro.tech/?post=8</guid>
</item>
<item>
    <title>我整理了一份 Github 搞钱榜单：适合程序员和独立开发者的变现项目清单</title>
    <link>https://www.hackpro.tech/?post=7</link>
    <description><![CDATA[<p>最近我看到一份很有意思的表格，名字就很直接：<strong>Github 搞钱榜单</strong>。</p>
<p>它把一批和“程序员变现”“独立开发”“AI 副业”“量化投资”“自媒体自动化”“远程工作”有关的 GitHub 项目整理到了一起。原始表格信息很多，但如果直接看表格，其实不太容易快速形成判断。</p>
<p>所以我干脆把它重新整理成一篇更适合阅读的博客文章：不是简单罗列，而是按方向拆开，顺便讲讲我对这些项目的理解。</p>
<p>先说结论：</p>
<blockquote>
<p>这份榜单最有价值的地方，不是告诉你“哪个项目最火”，而是让你看到：<br />
<strong>程序员想要提高收入，其实路径远不止接外包这一条。</strong></p>
</blockquote>
<p>你可以做产品、做内容、做开源、做交易、做自动化工具，甚至可以通过远程工作去获得更高单价。</p>
<h2>1. 一人公司 / 独立开发路线</h2>
<p>如果你对“自己做产品，自己赚钱”这条路感兴趣，这部分是最值得看的。</p>
<h3>我觉得值得先看的几个项目</h3>
<ul>
<li>
<p><strong>chinese-independent-developer</strong><br />
国内独立开发者项目汇总，Stars 很高，适合用来快速看看同行都在做什么、靠什么变现。</p>
</li>
<li>
<p><strong>one-person-businesses-methodology</strong><br />
这类项目的价值不在代码，而在方法论。它更像是一份从零搭建一人公司闭环的路线图。</p>
</li>
<li>
<p><strong>awesome-indie</strong><br />
汇总了独立开发和变现资源，适合做入口级收藏。</p>
</li>
<li>
<p><strong>howto-make-more-money</strong><br />
程序员副业赚钱思路合集，比较接地气，不是那种只讲大道理的资源。</p>
</li>
<li>
<p><strong>open-saas</strong> / <strong>nextjs/saas-starter</strong><br />
这类 SaaS 模板的价值非常直接：帮你少造轮子，更快把产品上线，早点验证有没有人愿意付费。</p>
</li>
<li>
<p><strong>Ghost</strong><br />
如果你想走“内容订阅 / 知识付费 / 独立博客”路线，Ghost 这种平台一直都很值得关注。</p>
</li>
</ul>
<h3>我对这一类项目的看法</h3>
<p>这一类仓库最容易让人产生一种错觉：</p>
<p><strong>只要我把模板跑起来，收入就会自己来。</strong></p>
<p>其实不是。</p>
<p>模板、脚手架、方法论当然都重要，但真正决定能不能赚到钱的，还是下面这些东西：</p>
<ul>
<li>你解决的问题是否真实存在</li>
<li>你能不能找到愿意付费的人</li>
<li>你有没有持续迭代的能力</li>
<li>你能不能把流量和产品闭环打通</li>
</ul>
<p>所以如果你要看这部分内容，我建议别只盯着“哪个模板最酷”，更应该关注：</p>
<p><strong>哪些项目是在帮你缩短从想法到收费的路径。</strong></p>
<h2>2. 金融投资 / AI 量化路线</h2>
<p>这一类项目看起来最“高端”，也最容易吸引技术人。</p>
<p>比如表格里提到的这些：</p>
<ul>
<li><strong>qlib</strong>：微软出品的 AI 量化投资平台</li>
<li><strong>vnpy</strong>：国内经典的量化交易框架</li>
<li><strong>yfinance</strong>：免费金融数据源，很多量化项目都会拿它做基础数据入口</li>
<li><strong>TradingAgents / TradingAgents-CN</strong>：多智能体交易框架</li>
<li><strong>dexter</strong>：金融深度投研 Agent</li>
<li><strong>ai-hedge-fund</strong>：模拟 AI 对冲基金协作分析</li>
<li><strong>daily_stock_analysis</strong>：LLM 驱动的每日行情分析器</li>
</ul>
<h3>这一类为什么看起来很诱人？</h3>
<p>因为它符合程序员的天然偏好：</p>
<ul>
<li>数据驱动</li>
<li>自动化</li>
<li>可回测</li>
<li>有“模型替我赚钱”的想象空间</li>
</ul>
<p>但我觉得这类项目最需要冷静看待。</p>
<p>原因很简单：</p>
<p><strong>会做分析系统 ≠ 能稳定赚钱。</strong></p>
<p>很多量化项目很强，技术实现也很漂亮，但金融市场不是一个“模型跑通就稳赢”的地方。它同时要求你理解：</p>
<ul>
<li>数据质量</li>
<li>策略逻辑</li>
<li>风险控制</li>
<li>交易成本</li>
<li>市场环境变化</li>
</ul>
<p>所以这一类项目更适合什么人？</p>
<p>我觉得更适合两类人：</p>
<ol>
<li>本来就对投资、量化、交易有长期兴趣的人  </li>
<li>希望把 AI / Agent / 自动化分析能力落地到金融研究的人</li>
</ol>
<p>如果你只是因为“听说量化能赚钱”就冲进去，这条路线的学习成本会比你想象中高很多。</p>
<h2>3. Crypto / 预测市场路线</h2>
<p>如果说量化投资偏传统金融，那这一部分就更偏加密世界和新型市场。</p>
<p>榜单里这部分包括：</p>
<ul>
<li><strong>CCXT</strong>：统一接入多交易所的基础库</li>
<li><strong>freqtrade</strong>：开源加密货币交易机器人</li>
<li><strong>Hummingbot</strong>：高频、做市、套利常见工具</li>
<li><strong>NOFX</strong>：自主 AI 交易助手</li>
<li><strong>py-clob-client</strong>：Polymarket 官方 Python SDK</li>
<li><strong>prediction-market-analysis</strong>：预测市场历史数据分析工具</li>
<li><strong>pmxt</strong>：预测市场版 CCXT</li>
</ul>
<h3>这类项目最大的吸引力是什么？</h3>
<p>就一句话：</p>
<p><strong>自动化 + 高频机会 + 全球市场。</strong></p>
<p>这对程序员来说确实很有吸引力，因为它天然适合：</p>
<ul>
<li>写脚本</li>
<li>跑策略</li>
<li>接 API</li>
<li>做套利监控</li>
<li>做自动化执行</li>
</ul>
<p>但问题同样很明显：</p>
<ul>
<li>风险更高</li>
<li>波动更大</li>
<li>平台规则和流动性问题更多</li>
<li>一不小心就会把“研究工具”当成“提款机”</li>
</ul>
<p>我的建议是，如果你对这一块感兴趣，先把它当成：</p>
<p><strong>一个“高风险、高反馈、非常适合技术探索”的领域，而不是一个轻松赚钱捷径。</strong></p>
<h2>4. 自媒体自动化路线</h2>
<p>这部分我觉得是最容易被普通程序员低估的。</p>
<p>很多技术人一看到“自媒体”就下意识觉得不专业，或者觉得这是内容创作者的事，和程序员关系不大。</p>
<p>但实际上，自媒体自动化可能恰恰是最适合程序员切入的方向之一。</p>
<p>榜单里这部分包括：</p>
<ul>
<li><strong>MoneyPrinterTurbo</strong>：自动生成带配音字幕的视频</li>
<li><strong>NarratoAI</strong>：影视解说自动化</li>
<li><strong>VideoLingo</strong>：视频翻译配音</li>
<li><strong>social-auto-upload</strong>：多平台自动分发</li>
<li><strong>md2wechat-skill</strong>：公众号排版发布工具</li>
<li><strong>XiaohongshuSkills</strong>：小红书自动化运营</li>
<li><strong>baoyu-skills</strong>：多平台内容创作与发布</li>
<li><strong>huobao-drama</strong>：短剧生成平台</li>
<li><strong>Toonflow</strong>：小说转短剧</li>
</ul>
<h3>为什么我会特别注意这类项目？</h3>
<p>因为这一类项目最贴近“AI 带来的生产力变化”。</p>
<p>它的核心不是某一个模型有多强，而是：</p>
<ul>
<li>选题</li>
<li>生成</li>
<li>配图 / 配音 / 剪辑</li>
<li>分发</li>
<li>账号矩阵运营</li>
</ul>
<p>这些原本分散的动作，开始被串成一条自动化链路。</p>
<p>这意味着什么？</p>
<p>意味着如果你既懂一点技术，又懂一点内容分发逻辑，那你很可能比纯内容创作者更容易把工具用起来。</p>
<p>当然，这条路也不是“把工具跑起来就自动赚钱”。</p>
<p>最终决定效果的，还是：</p>
<ul>
<li>你做什么内容</li>
<li>发到哪个平台</li>
<li>你有没有持续更新能力</li>
<li>你的内容是否能抓住目标用户</li>
</ul>
<p>但和前面几条路线相比，这条路的一个优势是：</p>
<p><strong>更容易低成本试错。</strong></p>
<h2>5. 远程工作资源路线</h2>
<p>还有一类人，不一定想自己做产品，也不一定想折腾副业自动化，而是单纯想：</p>
<p><strong>提升收入，但不一定非要创业。</strong></p>
<p>那远程工作其实就是一条很现实的路。</p>
<p>榜单里这一部分包括：</p>
<ul>
<li><strong>awesome-remote-job</strong></li>
<li><strong>remote-jobs</strong></li>
<li><strong>greatghoul/remote-working</strong></li>
<li><strong>established-remote</strong></li>
<li><strong>TheRemoteFreelancer</strong></li>
</ul>
<h3>这条路为什么值得重视？</h3>
<p>因为很多人一提“搞钱”，就只想到：</p>
<ul>
<li>做副业</li>
<li>做产品</li>
<li>接私单</li>
<li>做流量</li>
</ul>
<p>但实际上，<strong>提高单价本身就是最稳的变现方式之一。</strong></p>
<p>如果你能通过远程岗位、国际化机会、自由职业平台，把自己的工作单价提上去，那往往比从零做一个副业项目更稳。</p>
<p>这条路的优点是：</p>
<ul>
<li>现金流更稳定</li>
<li>不一定要承担产品失败风险</li>
<li>更适合有成熟技能的人</li>
</ul>
<p>缺点也很明显：</p>
<ul>
<li>对英语、沟通、协作要求更高</li>
<li>竞争同样不小</li>
<li>你本质上还是在出售时间</li>
</ul>
<p>所以它不是“最自由”的路，但很可能是很多程序员最应该优先考虑的路。</p>
<h2>这份榜单最有价值的，不是项目本身，而是视角</h2>
<p>我看完这份表格后，最大的感受其实不是“我又收藏了一堆仓库”，而是：</p>
<p><strong>程序员提高收入这件事，真的可以从多个维度同时思考。</strong></p>
<p>你至少可以从这些方向里找到适合自己的切口：</p>
<ul>
<li>想做自己的产品：看一人公司 / SaaS 模板</li>
<li>想研究自动化交易：看量化 / Crypto / 预测市场</li>
<li>想做内容与流量：看自媒体自动化</li>
<li>想稳一点提高收入：看远程工作资源</li>
</ul>
<p>这几条路的共同点是：</p>
<p>它们都不是“今天看一个仓库，明天就赚到钱”的路径。</p>
<p>但它们都在帮你理解一件事：</p>
<blockquote>
<p><strong>赚钱从来不是单点技巧，而是能力、渠道、工具和执行力的组合。</strong></p>
</blockquote>
<h2>写在最后</h2>
<p>如果你平时也在关注“程序员如何提高收入”这个话题，我觉得这种整理好的资源表格是值得看的。</p>
<p>但更重要的是，不要只停留在收藏。</p>
<p>与其把几十个 GitHub 仓库全部 star 一遍，不如认真挑一条最适合自己的路线，然后真正跑一遍。</p>
<p>有的人适合做 SaaS，<br />
有的人适合做内容，<br />
有的人适合做交易系统，<br />
有的人适合先去拿一个更高单价的远程岗位。</p>
<p>路线不同，但有一件事是一样的：</p>
<p><strong>真正拉开差距的，不是信息，而是把信息变成行动。</strong></p>
<hr />
<h3>我参考的表格方向</h3>
<p>这篇文章整理自一份名为 <strong>Github 搞钱榜单</strong> 的资源表，数据基准时间为 <strong>2026-03-30</strong>。</p>]]></description>
    <pubDate>Mon, 30 Mar 2026 18:52:29 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://www.hackpro.tech/?post=7</guid>
</item>
<item>
    <title>我最近发现了一个很有意思的创作者工具项目：智子X</title>
    <link>https://www.hackpro.tech/?post=6</link>
    <description><![CDATA[<p>最近逛 GitHub 的时候，我发现了一个挺有意思的项目，名字叫 <strong>智子X</strong>。</p>
<p>它的介绍里有一句话，我印象很深：</p>
<blockquote>
<p><strong>智子X，不是工具堆砌，是给创作者的一间实验室。</strong></p>
</blockquote>
<p>说实话，现在“AI 创作工具”这个方向已经很卷了。<br />
各种写作工具、内容生成器、文案平台、素材站层出不穷，很多产品第一眼看上去都很厉害，功能列表拉得特别长，但真正用起来时，常常会有一种感觉：</p>
<p><strong>看起来什么都能做，实际上什么都做得不够深。</strong></p>
<p>而智子X给我的感觉，稍微有点不一样。</p>
<p>它不像是在拼命证明“我功能很多”，反而更像是在认真回答一个问题：</p>
<p><strong>如果真的站在内容创作者的视角去思考，一个好用的创作工具，到底应该长什么样？</strong></p>
<h2>它在做什么？</h2>
<p>从 GitHub 仓库的介绍来看，智子X目前主要围绕三块能力在做：</p>
<ul>
<li><strong>写作实验室</strong></li>
<li><strong>媒体解析</strong></li>
<li><strong>图片去重</strong></li>
</ul>
<p>如果只看名字，这三个功能好像有点分散。<br />
但如果把它们放回到“内容创作流程”里，其实就很好理解了。</p>
<p>一个内容创作者平时的工作，大概离不开这些环节：</p>
<ol>
<li>找素材  </li>
<li>分析内容风格  </li>
<li>组织写作结构  </li>
<li>生成或辅助生成内容  </li>
<li>处理配图  </li>
<li>优化成品并发布  </li>
</ol>
<p>而智子X做的事情，本质上就是围着这条链路，去补足创作过程中最容易卡住、最耗时间的几个点。</p>
<p>所以它不是那种“单点特别炫”的工具，而更像是一套围绕创作流程搭出来的工作台。</p>
<h2>我觉得它最特别的地方，不是功能，而是思路</h2>
<p>我看完这个项目后，最大的感受不是“这个工具真多”，而是：</p>
<p><strong>它的产品思路其实挺克制的。</strong></p>
<p>它一直在强调几件事：</p>
<ul>
<li>不追求功能数量</li>
<li>每一个能力都要真实可用</li>
<li>逻辑尽量透明</li>
<li>数据尽量留在本地</li>
<li>工具是帮助创作者，而不是替代创作者</li>
</ul>
<p>这点我挺认同。</p>
<p>因为现在很多工具都很喜欢做一件事：<br />
给用户一种“你什么都不用想，点几个按钮就能搞定一切”的感觉。</p>
<p>这种思路短期看很讨喜，但问题也很明显：<br />
你越依赖平台，越容易失去对自己创作流程的理解和控制。</p>
<p>而智子X把自己叫做“实验室”，我觉得这个说法其实挺准确。</p>
<p>“平台”的逻辑，往往是给你标准答案；<br />
“实验室”的逻辑，更像是给你方法、工具和试错空间。</p>
<p>这两者差别其实很大。</p>
<h2>写作实验室，是我最感兴趣的一部分</h2>
<p>如果说我对这个项目里哪部分最感兴趣，那一定是 <strong>写作实验室</strong>。</p>
<p>因为现在很多所谓的 AI 写作产品，本质上都还停留在一个很浅的阶段：</p>
<ul>
<li>给一段提示词</li>
<li>输出一篇看起来完整的文章</li>
<li>然后结束</li>
</ul>
<p>这当然有用，但也很容易遇到瓶颈。<br />
因为真正困扰内容创作者的，很多时候并不是“写不出一篇文章”，而是：</p>
<ul>
<li>怎么稳定写出<strong>有自己风格</strong>的内容？</li>
<li>怎么让内容不是一眼 AI 味？</li>
<li>怎么把自己的表达方式沉淀下来？</li>
<li>怎么让创作从“靠感觉”变成“有结构、有方法”的过程？</li>
</ul>
<p>从项目介绍来看，智子X想做的，并不是简单的“生成”，而是往更底层走：</p>
<ul>
<li>做风格建模</li>
<li>做参数量化</li>
<li>把风格变成可复用的 Skill</li>
<li>用多层约束去驱动生成，而不是生成完再去硬改</li>
</ul>
<p>这一点我觉得很有意思。</p>
<p>因为如果它真能把“写作风格”这件事拆成一套可分析、可配置、可复用的体系，那它做的就不是一个普通写作工具，而是在尝试解决一个更难的问题：</p>
<p><strong>怎么把创作者的风格，变成一种可积累的资产。</strong></p>
<p>这一点，其实比“帮你写一篇文章”更有价值。</p>
<h2>它对“数据主权”的强调，也很难得</h2>
<p>另一个我比较在意的点，是它反复提到“数据主权”。</p>
<p>这个词听起来有点大，但翻译成人话，其实就是：</p>
<p><strong>你的素材、你的内容、你的处理过程，最好尽量掌握在你自己手里。</strong></p>
<p>从项目介绍来看，它比较强调这些原则：</p>
<ul>
<li>数据尽量本地处理</li>
<li>不做不必要的中转</li>
<li>浏览器直接参与能力执行</li>
<li>用户对数据有更强控制权</li>
</ul>
<p>我觉得这点挺重要。</p>
<p>因为对于内容创作者来说，真正值钱的从来不只是最后那篇文章，而是整条创作链路里的东西：</p>
<ul>
<li>你看了什么素材</li>
<li>你如何做判断</li>
<li>你偏好的表达方式是什么</li>
<li>你如何处理图片和内容</li>
<li>你怎么逐渐形成自己的方法论</li>
</ul>
<p>这些东西一旦积累起来，价值是很高的。</p>
<p>所以一个工具如果真的愿意把控制权更多地留给用户，而不是一味把所有行为都吸进自己的系统里，这种取向本身就值得多看一眼。</p>
<h2>媒体解析和图片去重，也不是“凑功能”</h2>
<p>有些项目一做大，就容易出现一个问题：<br />
功能越来越多，但彼此之间没什么关系。</p>
<p>不过智子X现在这两个方向——<strong>媒体解析</strong> 和 <strong>图片去重</strong>，我觉得并不是随便加上去的。</p>
<h3>1. 媒体解析</h3>
<p>对内容创作者来说，“获取素材”本身就是高频需求。</p>
<p>如果这个环节体验不好，后面的内容分析、整理、创作其实都会受影响。<br />
所以媒体解析这个能力，看起来像一个小工具，但实际上它是整个创作流程的上游入口。</p>
<p>而且从项目介绍来看，它强调的是：</p>
<ul>
<li>多平台支持</li>
<li>浏览器直连</li>
<li>不走中心化中转</li>
<li>更注重隐私和边界</li>
</ul>
<p>这就让它不仅仅像一个“下载器”，而更像是创作工作流中的采集组件。</p>
<h3>2. 图片去重</h3>
<p>图片去重这个功能，我觉得很容易被低估。</p>
<p>很多人以为图片处理无非就是裁剪、调色、加滤镜，但对于经常做内容分发的人来说，图片“重复度”其实是个非常现实的问题。</p>
<p>如果这个工具真的能做到：</p>
<ul>
<li>在浏览器里完成处理</li>
<li>做指纹检测</li>
<li>还能做更细致的图像差异化调整</li>
</ul>
<p>那它就不是一个普通的图片小工具，而是一个非常贴近实际场景的生产辅助工具。</p>
<h2>我为什么会注意这种项目？</h2>
<p>因为我越来越觉得，未来真正有价值的创作工具，不会只是“帮你生成一段东西”的工具，而是能够帮助创作者建立完整工作流的工具。</p>
<p>单点能力，其实很容易被复制。</p>
<p>今天一个平台能做标题生成，明天就会出现十个同类产品。<br />
今天一个工具能做爆款文案，后天别人也能接 API 做出来。</p>
<p>但如果一个产品真的理解创作者的工作过程，理解从素材、分析、建模、生成到优化的整条链路，并且在关键节点上提供靠谱支持，那它就有机会建立起更长期的价值。</p>
<p>从这个角度看，智子X至少是在往一个我比较认可的方向上走。</p>
<p>它现在是不是已经足够成熟，我还没真正深度体验过，所以不急着下结论。<br />
但至少从公开项目介绍来看，它不是那种“看起来很热闹，其实很空”的工具站。</p>
<h2>写在最后</h2>
<p>如果你平时也在关注 <strong>AI + 内容创作</strong> 这个方向，我觉得智子X这个项目值得看一眼：</p>
<ul>
<li>GitHub：<a href="https://github.com/zhiziX/zhiziX">https://github.com/zhiziX/zhiziX</a></li>
<li>官网：<a href="https://zhizix.com/">https://zhizix.com/</a></li>
</ul>
<p>我自己看完这个项目后，最在意的反而不是它列出来的那些功能，而是它背后的那个问题：</p>
<p><strong>创作者真正需要的，到底是更多按钮，还是更强的方法论和控制力？</strong></p>
<p>至少从目前公开的信息来看，智子X想做的，明显更接近后者。</p>]]></description>
    <pubDate>Mon, 30 Mar 2026 18:13:46 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://www.hackpro.tech/?post=6</guid>
</item>
<item>
    <title>我为什么开始用 AI 重构个人开发工作流</title>
    <link>https://www.hackpro.tech/?post=5</link>
    <description><![CDATA[<p>这段时间，我越来越明显地感觉到：个人开发最稀缺的不是技术能力，而是稳定的执行力。</p>
<p>以前我做项目，习惯是自己从头到尾一点点啃：想需求、查资料、搭前端、写后端、部署上线、修 bug。这样的方式当然能做成事，但问题也很明显——切换成本太高，很多时间其实消耗在重复劳动上，而不是思考真正重要的事情。</p>
<p>后来我开始把 AI 当成开发流程的一部分，而不是一个单独的问答工具。这个变化看起来不大，但对我的工作方式影响非常明显。</p>
<h2>AI 真正帮我解决的，不是“不会写代码”</h2>
<p>很多人理解 AI，还停留在“让它帮我写一段代码”这个层面。这个用法当然有价值，但我越来越觉得，这只是最浅的一层。</p>
<p>对我来说，AI 最大的意义有三个：</p>
<ol>
<li>快速整理思路</li>
<li>降低重复劳动的时间成本</li>
<li>把零散任务串成可执行的流程</li>
</ol>
<p>比如我在做一个小项目时，常常不是卡在某一行代码不会写，而是卡在这些问题上：</p>
<ul>
<li>这个功能到底该怎么拆？</li>
<li>先做前端还是先做接口？</li>
<li>部署应该选最省钱的方案还是最省事的方案？</li>
<li>文档、测试、上线说明这些杂事什么时候补？</li>
</ul>
<p>这些问题看起来不难，但特别消耗心力。AI 在这里最大的价值，是帮我把混乱的信息先整理成结构化的行动方案。</p>
<h2>我现在是怎么用 AI 的</h2>
<p>我现在更习惯把 AI 放进一个完整的工作流里，而不是有问题了才打开问一句。</p>
<h3>1. 需求拆解</h3>
<p>当我拿到一个想法时，第一步不是立刻开写，而是先让 AI 帮我做一版初步拆解：</p>
<ul>
<li>核心功能有哪些</li>
<li>最小可用版本应该长什么样</li>
<li>哪些功能现在不值得做</li>
<li>数据结构大概怎么设计</li>
</ul>
<p>这样做的好处，是能明显减少“做着做着跑偏”的情况。</p>
<h3>2. 技术选型对比</h3>
<p>以前我选技术栈，经常会在不同方案之间来回摇摆。比如：</p>
<ul>
<li>Next.js 还是传统前后端分离</li>
<li>Vercel 还是云服务器</li>
<li>MySQL 还是 SQLite</li>
<li>要不要加管理后台</li>
</ul>
<p>现在我会先让 AI 按项目规模、预算、维护成本、部署复杂度几个维度做对比。虽然最终决定还是我自己来拍板，但这个过程能帮我少踩很多信息不对称的坑。</p>
<h3>3. 编码协作</h3>
<p>真正进入开发阶段后，AI 更像是一个随时在线的协作者。</p>
<p>我会让它：</p>
<ul>
<li>生成基础代码骨架</li>
<li>补充接口文档</li>
<li>检查逻辑漏洞</li>
<li>帮我重构命名和结构</li>
<li>快速写一些重复性很强的 CRUD 代码</li>
</ul>
<p>这里有一个前提：我不会把它生成的内容原封不动地丢进项目里。</p>
<p>AI 很擅长“先给你一个八十分的版本”，但最后那二十分，还是要靠人来判断。尤其是涉及安全、权限、边界情况的时候，必须自己过一遍。</p>
<h3>4. 部署和运维辅助</h3>
<p>这部分是我最近感受最深的。</p>
<p>很多个人项目其实不是死在开发阶段，而是死在部署和维护阶段。你把功能写出来了，但上线麻烦、环境不稳定、日志不会看、报错找不到入口，项目就很容易烂尾。</p>
<p>AI 在这里很适合做这些事：</p>
<ul>
<li>帮你梳理部署步骤</li>
<li>解释报错日志</li>
<li>生成 Nginx / PM2 / Docker 配置</li>
<li>检查上线前遗漏项</li>
<li>整理发布说明和运维文档</li>
</ul>
<p>这些工作单独看都不复杂，但加起来会吃掉很多时间。AI 的价值就是把这些碎片时间重新收回来。</p>
<h2>AI 不能替代的部分，反而更重要了</h2>
<p>AI 用得越多，我反而越确定一件事：真正有价值的，不是“写代码”这件事本身，而是判断做什么、为什么做、做到什么程度。</p>
<p>AI 可以加速执行，但它不能替你承担结果。</p>
<p>比如：</p>
<ul>
<li>哪个需求值得做，哪个只是自我感动</li>
<li>哪种架构适合当前阶段，而不是理论上最优</li>
<li>什么时候该追求完美，什么时候应该尽快上线</li>
<li>用户真正需要的到底是什么</li>
</ul>
<p>这些事情，本质上还是人的工作。</p>
<p>所以我现在越来越不把 AI 看成“替代者”，而是把它看成一个放大器：</p>
<ul>
<li>你的思路清晰，它会让你更高效</li>
<li>你的流程混乱，它也只会更快地制造混乱</li>
</ul>
<h2>对个人开发者来说，最重要的是先用起来</h2>
<p>如果你是个人开发者，我很建议尽早把 AI 真正用进自己的工作流里，而不是停留在“偶尔问几个问题”。</p>
<p>你不需要一上来就搞得很复杂，哪怕只是从下面几件小事开始：</p>
<ul>
<li>写功能前，先让 AI 帮你拆任务</li>
<li>部署前，让 AI 帮你列检查清单</li>
<li>遇到报错时，让 AI 先解释日志含义</li>
<li>写完功能后，让 AI 帮你补文档</li>
</ul>
<p>这些动作看起来都很小，但长期坚持下来，会明显感受到效率差异。</p>
<h2>写在最后</h2>
<p>我现在越来越相信，未来个人开发的竞争力，不只是“你会不会写代码”，而是：你会不会借助工具，把自己的想法更快、更稳定地变成真实可用的产品。</p>
<p>AI 不是答案，但它确实正在改变做事的方法。</p>
<p>对我来说，这种改变已经开始了。</p>
<p>如果你也在尝试把 AI 用进自己的开发流程，欢迎留言聊聊你现在最常用的方式。</p>]]></description>
    <pubDate>Mon, 30 Mar 2026 17:06:56 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://www.hackpro.tech/?post=5</guid>
</item>
<item>
    <title>demo</title>
    <link>https://www.hackpro.tech/?post=4</link>
    <description><![CDATA[<p><img src="https://dilv.hackpro.tech/202603/3edb1773061584.jpg" alt="" /></p>]]></description>
    <pubDate>Mon, 09 Mar 2026 21:06:14 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://www.hackpro.tech/?post=4</guid>
</item>
<item>
    <title>放弃React+Node.js后，我发现了更简单的全栈方案</title>
    <link>https://www.hackpro.tech/?post=3</link>
    <description><![CDATA[<p>最近帮朋友做了一个小项目，用来记录学院的桶装水配送情况。本来以为是个很简单的需求，没想到做出来之后，发现这个小系统还挺有意思的。</p>
<h2>需求很简单</h2>
<p>朋友在学院负责桶装水配送，每天要记录：</p>
<ul>
<li>送了多少桶普通水</li>
<li>送了多少桶农夫山泉</li>
<li>拿走了多少个空桶</li>
<li>还剩多少个空桶</li>
</ul>
<p>之前用纸质记录，容易丢失，也不方便查询历史数据。他希望有个简单的网页系统，能在手机上操作，数据不会丢失。</p>
<h2>项目截图</h2>
<p><img src="https://files.mdnice.com/user/49613/8bd8a08b-d9ca-4c81-832f-e7799a2ca4fe.png" alt="" /><br />
<img src="https://dilv.hackpro.tech/202603/3edb1773061773.jpg" alt="" /></p>
<p><img src="https://files.mdnice.com/user/49613/832b1700-eb11-43ba-ba12-9722cd6ad4c1.png" alt="" /></p>
<p><img src="https://files.mdnice.com/user/49613/0c8c849b-f07b-46ca-be8e-33e60992e094.png" alt="" /></p>
<h2>技术选择</h2>
<p>这种小系统，最重要的是简单可靠。我选择了 Cloudflare Workers + KV 存储的方案。</p>
<p><strong>为什么选择 Cloudflare Workers？</strong></p>
<ol>
<li><strong>零服务器维护</strong>：不用买服务器，不用配置环境，代码部署后就能跑</li>
<li><strong>全球分发</strong>：Cloudflare 的边缘网络覆盖全球，访问速度快</li>
<li><strong>成本极低</strong>：免费额度对小项目完全够用</li>
<li><strong>开发简单</strong>：就是写 JavaScript，没有复杂的框架</li>
</ol>
<p><strong>为什么用 KV 存储？</strong></p>
<p>Cloudflare KV 是一个分布式键值存储，特点是：</p>
<ul>
<li>全球同步</li>
<li>读取速度极快</li>
<li>写入有一定延迟</li>
</ul>
<p>对于送水记录这种场景，数据量小，读多写少，KV 存储完全够用。</p>
<h2>架构设计</h2>
<p>整个系统核心文件就是一个 JavaScript 文件，包含：</p>
<pre><code class="language-javascript">export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const path = url.pathname;

    // 路由处理
    if (path === '/') {
      return new Response(getHTML(), {
        headers: { 'Content-Type': 'text/html' }
      });
    }

    if (path === '/api/delivery' &amp;&amp; request.method === 'POST') {
      return await handleDelivery(request, env);
    }

    // 其他 API 路由...
  }
};</code></pre>
<p>前后端代码都在一个文件里，HTML、CSS、JavaScript 全部内联。这样做的好处是部署简单，坏处是代码有点长（1400多行）。</p>
<h2>核心功能实现</h2>
<p><strong>1. 数据存储</strong></p>
<p>每条送水记录存储为一个 KV 键值对：</p>
<pre><code class="language-javascript">const record = {
  date: '2024-01-15',
  timestamp: '2024-01-15T10:30:00.000Z',
  normalWater: 5,
  nongfuWater: 3,
  totalDelivered: 8,
  emptyBucketsTaken: 6,
  remainingEmptyBuckets: 12
};

const recordKey = `delivery_${timestamp.replace(/[:.]/g, '_')}`;
await env.WATER_KV.put(recordKey, JSON.stringify(record));</code></pre>
<p><strong>2. 空桶计算</strong></p>
<p>这是系统的核心逻辑：</p>
<pre><code class="language-javascript">// 获取当前空桶数量
const currentStatus = await env.WATER_KV.get('current_status');
let status = currentStatus ? JSON.parse(currentStatus) : { emptyBuckets: 0 };

// 计算新的空桶数量
const deliveredBuckets = normalWater + nongfuWater;
status.emptyBuckets = status.emptyBuckets + deliveredBuckets - emptyBuckets;

// 防止空桶数量为负
if (status.emptyBuckets &lt; 0) {
  return new Response(JSON.stringify({ 
    error: `空桶数量不足，当前只有 ${status.emptyBuckets + emptyBuckets} 个空桶` 
  }), { status: 400 });
}</code></pre>
<p><strong>3. 用户认证</strong></p>
<p>简单的用户名密码验证：</p>
<pre><code class="language-javascript">if (username === env.USERNAME &amp;&amp; password === env.PASSWORD) {
  return new Response(JSON.stringify({ success: true }));
}</code></pre>
<p>用户名和密码存储在环境变量中，登录状态保存在浏览器的 localStorage。</p>
<h2>前端设计</h2>
<p>界面采用了现代化的设计风格：</p>
<ul>
<li>渐变色背景</li>
<li>毛玻璃效果</li>
<li>响应式布局</li>
<li>流畅的动画过渡</li>
</ul>
<p>关键是要在手机上好用，所以做了很多移动端优化：</p>
<pre><code class="language-css">@media (max-width: 768px) {
  .container {
    margin: 10px;
    border-radius: 8px;
  }

  .header h1 {
    font-size: 1.8em;
  }

  .form-section {
    padding: 20px;
  }
}</code></pre>
<h2>部署过程</h2>
<p>部署非常简单：</p>
<ol>
<li>安装 Wrangler CLI</li>
<li>创建 KV 命名空间</li>
<li>配置环境变量</li>
<li>一键部署</li>
</ol>
<pre><code class="language-bash">npm install -g wrangler
wrangler kv:namespace create "WATER_KV"
wrangler publish</code></pre>
<p>部署完成后，就得到一个 <code>https://xxx.workers.dev</code> 的地址，全球都能访问。</p>
<h2>使用体验</h2>
<p>系统上线后，朋友反馈很好：</p>
<ol>
<li><strong>操作简单</strong>：打开网页，输入数字，点击提交</li>
<li><strong>响应快速</strong>：得益于 Cloudflare 的边缘网络</li>
<li><strong>数据可靠</strong>：再也不用担心记录丢失</li>
<li><strong>查询方便</strong>：可以按日期筛选历史记录</li>
<li><strong>导出功能</strong>：支持导出 Excel 格式</li>
</ol>
<h2>成本分析</h2>
<p>Cloudflare Workers 的免费额度：</p>
<ul>
<li>每天 100,000 次请求</li>
<li>KV 存储 1GB 空间</li>
<li>每天 1,000 次 KV 写入</li>
<li>每天 100,000 次 KV 读取</li>
</ul>
<p>对于这个小系统来说，免费额度完全够用。即使超出免费额度，付费价格也很便宜。</p>
<h2>技术思考</h2>
<p><strong>简单就是美</strong></p>
<p>很多时候，我们习惯用复杂的技术栈：React + Node.js + MySQL + Redis + Nginx...但对于简单的需求，这些可能都是过度设计。</p>
<p>一个 JavaScript 文件，解决了前端、后端、数据库、部署的所有问题。虽然代码组织不够优雅，但胜在简单可靠。</p>
<p><strong>边缘计算的价值</strong></p>
<p>Cloudflare Workers 运行在边缘节点上，用户访问时会自动选择最近的节点。这种架构对于全球化应用特别有价值。</p>
<p><strong>无服务器的优势</strong></p>
<p>传统的服务器部署，需要考虑：</p>
<ul>
<li>服务器配置和维护</li>
<li>负载均衡</li>
<li>数据库备份</li>
<li>监控告警</li>
<li>安全更新</li>
</ul>
<p>而 Serverless 架构把这些都交给了云服务商，开发者只需要关注业务逻辑。</p>
<h2>可能的改进</h2>
<p>如果要继续完善这个系统，可以考虑：</p>
<ol>
<li><strong>数据分析</strong>：添加图表展示送水趋势</li>
<li><strong>通知功能</strong>：空桶不足时自动提醒</li>
<li><strong>多用户支持</strong>：不同配送员独立记录</li>
<li><strong>API 接口</strong>：提供标准的 REST API</li>
<li><strong>数据备份</strong>：定期备份到其他存储服务</li>
</ol>
<h2>总结</h2>
<p>Cloudflare Workers + KV 存储，虽然不是最新最热的技术，但对于这个场景来说，是最合适的选择。它提供了：</p>
<ul>
<li>足够的性能</li>
<li>极低的成本</li>
<li>简单的开发体验</li>
<li>可靠的运行环境</li>
</ul>
<hr />
<p>项目代码已开源，感兴趣的朋友可以参考</p>
<p><img src="https://files.mdnice.com/user/49613/4c83f751-5ec6-4835-a47c-efdba16bdaa8.png" alt="" /></p>
<blockquote>
<p><a href="https://github.com/chris8611/water-delivery-tracker">https://github.com/chris8611/water-delivery-tracker</a></p>
</blockquote>]]></description>
    <pubDate>Sun, 08 Mar 2026 13:27:57 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://www.hackpro.tech/?post=3</guid>
</item>
<item>
    <title>我是如何用Vercel零成本部署小程序后台的</title>
    <link>https://www.hackpro.tech/?post=2</link>
    <description><![CDATA[<blockquote>
<p>最近在做一个微信小程序项目，后台需要部署到云端，但是后端业务相对简单，购买服务器的话超出预算了。经过一番调研，发现 Vercel 是个不错的选择：免费、简单、速度快。今天就来分享一下具体的部署过程。</p>
</blockquote>
<h2>项目后台演示</h2>
<p><img src="https://files.mdnice.com/user/49613/4355baeb-20bc-4180-9383-6b09c5209594.png" alt="" /></p>
<p><img src="https://files.mdnice.com/user/49613/5786740a-794f-4fb7-9d35-26f0e68852fb.png" alt="" /></p>
<h2>为什么选择 Vercel</h2>
<p>传统的服务器部署需要自己管理服务器、配置环境、处理运维问题。而 Vercel 这类 Serverless 平台的出现<strong>，让部署和API部署变得极其简单。</strong></p>
<p>对于小程序后台来说，Vercel 有几个明显的优势：</p>
<ol>
<li><strong>零配置部署</strong>：推送代码就能自动部署</li>
<li><strong>全球 CDN</strong>：访问速度快</li>
<li><strong>免费额度</strong>：个人项目完全够用</li>
<li><strong>自动 HTTPS</strong>：省去证书配置的麻烦</li>
</ol>
<h2>项目结构</h2>
<p>我们的小程序后台是一个标准的 Node.js + Express 应用，主要文件结构如下：</p>
<pre><code>backend/
├── app.js              # 主应用文件
├── package.json        # 依赖配置
├── vercel.json         # Vercel 配置文件
├── deploy.sh           # 部署脚本
├── .env                # 环境变量
└── admin/              # 管理后台静态文件</code></pre>
<h2>核心配置文件</h2>
<h3>1. vercel.json</h3>
<p>这是 Vercel 的配置文件，告诉 Vercel 如何构建和运行我们的应用：</p>
<pre><code class="language-json:/Users/mac/Desktop/code/zhao/backend/vercel.json">{
  "version": 2,
  "builds": [
    {
      "src": "app.js",
      "use": "@vercel/node"
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "/app.js"
    }
  ],
  "env": {
    "NODE_ENV": "production",
    "VERCEL": "1"
  }
}</code></pre>
<p>这个配置很简单：</p>
<ul>
<li><code>builds</code> 指定构建规则，使用 <code>@vercel/node</code> 来处理 Node.js 应用</li>
<li><code>routes</code> 将所有请求都路由到 <code>app.js</code></li>
<li><code>env</code> 设置环境变量</li>
</ul>
<h3>2. package.json</h3>
<p>关键是要有正确的启动脚本：</p>
<pre><code class="language-json:/Users/mac/Desktop/code/zhao/backend/package.json">{
  "name": "backend",
  "version": "1.0.0",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js",
    "vercel-build": "echo \"Vercel build completed\""
  },
  "dependencies": {
    "express": "^5.1.0",
    "cors": "^2.8.5",
    "mysql2": "^3.14.3",
    "jsonwebtoken": "^9.0.2",
    "bcryptjs": "^3.0.2",
    "dotenv": "^17.2.1",
    "axios": "^1.11.0",
    "multer": "^2.0.2",
    "sharp": "^0.34.3",
    "sqlite3": "^5.1.7"
  }
}</code></pre>
<h3>3. 应用入口文件</h3>
<p><code>app.js</code> 是我们的主应用文件，需要注意几个关键点：</p>
<pre><code class="language-javascript:/Users/mac/Desktop/code/zhao/backend/app.js">const express = require('express');
const cors = require('cors');
const mysql = require('mysql2/promise');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 3000;

// CORS 配置 - 重要！
app.use(cors({
  origin: true,
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With']
}));

// 静态文件服务
app.use('/admin', express.static(path.join(__dirname, './admin')));

// 数据库配置
const dbConfig = {
  host: process.env.DB_HOST || 'localhost',
  port: process.env.DB_PORT || 3306,
  user: process.env.DB_USER || 'root',
  password: process.env.DB_PASSWORD || '',
  database: process.env.DB_NAME || 'zhaoyimei_db'
};

// 重要：Vercel 环境下不启动监听
if (process.env.NODE_ENV !== 'production' || !process.env.VERCEL) {
  const server = app.listen(PORT, '0.0.0.0', () =&gt; {
    console.log(`服务器运行在端口 ${PORT}`);
  });
}

// 导出 app 供 Vercel 使用
module.exports = app;</code></pre>
<p>最后两行很关键。在 Vercel 环境下，我们不需要启动 HTTP 服务器，只需要导出 Express 应用实例即可。</p>
<h2>部署脚本</h2>
<p>为了简化部署流程，我写了一个自动化脚本：</p>
<pre><code class="language-bash:/Users/mac/Desktop/code/zhao/backend/deploy.sh">#!/bin/bash

echo "🚀 开始部署到 Vercel..."

# 检查是否安装了 Vercel CLI
if ! command -v vercel &amp;&gt; /dev/null; then
    echo "❌ Vercel CLI 未安装，正在安装..."
    npm install -g vercel
fi

# 检查是否已登录
echo "🔐 检查 Vercel 登录状态..."
if ! vercel whoami &amp;&gt; /dev/null; then
    echo "📝 请先登录 Vercel:"
    vercel login
fi

# 部署到生产环境
echo "📦 部署到生产环境..."
vercel --prod

echo "✅ 部署完成！"
echo "📋 请记住在 Vercel Dashboard 中配置环境变量"</code></pre>
<h2>环境变量配置</h2>
<p>部署完成后，需要在 Vercel Dashboard 中配置环境变量。我们的项目需要这些变量：</p>
<ul>
<li><code>DB_HOST</code> - 数据库主机</li>
<li><code>DB_PORT</code> - 数据库端口</li>
<li><code>DB_USER</code> - 数据库用户名</li>
<li><code>DB_PASSWORD</code> - 数据库密码</li>
<li><code>DB_NAME</code> - 数据库名称</li>
<li><code>JWT_SECRET</code> - JWT 密钥</li>
<li><code>WECHAT_APPID</code> - 微信小程序 AppID</li>
<li><code>WECHAT_SECRET</code> - 微信小程序密钥</li>
</ul>
<p>在 Vercel Dashboard 的项目设置页面，找到 &quot;Environment Variables&quot; 选项，逐一添加这些变量。</p>
<h2>数据库选择</h2>
<p>我用的sqlpub的开发版数据库，数据库版本是mysql8.4.0，一年9元，1G容量。也有免费版的500M容量，如果测试用可以免费申请使用这个版本的</p>
<p><img src="https://files.mdnice.com/user/49613/adcfea15-931d-4b7c-adcc-f2a2e23ce6b2.png" alt="" /></p>
<blockquote>
<p>网址：<a href="https://sqlpub.com/">https://sqlpub.com/</a></p>
</blockquote>
<h2>部署步骤</h2>
<p>整个部署过程非常简单：<br />
直接运行我们的部署脚本：</p>
<pre><code class="language-bash">chmod +x deploy.sh &amp;&amp; ./deploy.sh</code></pre>
<h2>常见问题</h2>
<h3>1. CORS 问题</h3>
<p>小程序访问后台 API 时，经常遇到跨域问题。解决方案是在 Express 中正确配置 CORS：</p>
<pre><code class="language-javascript">app.use(cors({
  origin: true, // 允许所有来源
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
}));</code></pre>
<h3>2. 静态文件服务</h3>
<p>如果你的后台包含管理界面等静态文件，需要正确配置静态文件服务：</p>
<pre><code class="language-javascript">app.use('/admin', express.static(path.join(__dirname, './admin')));</code></pre>
<h3>3. 数据库连接</h3>
<p>建议使用连接池来管理数据库连接，避免连接数过多的问题：</p>
<pre><code class="language-javascript">const pool = mysql.createPool(dbConfig);</code></pre>
<h2>访问优化</h2>
<h3>自定义域名</h3>
<p>部署成功后vercel会免费分配一个域名，但是国内访问效果不佳，需要自定义域名</p>
<p><img src="https://files.mdnice.com/user/49613/5679cfdd-1be2-4265-8f70-05834a3bd7d4.png" alt="" /></p>
<p><img src="https://files.mdnice.com/user/49613/6f6633cb-b2f1-4d9e-b0eb-dd8e6c2858e0.png" alt="" /></p>
<h3>服务器位置选择</h3>
<p>系统默认部署到其他洲的服务器，这就让我们的访问速度比较慢，需要手动更改地区为亚洲的HongKong</p>
<p><img src="https://files.mdnice.com/user/49613/36d70d9f-03b6-49bd-99ab-dbbb8bda49aa.png" alt="" /></p>
<h2>总结</h2>
<p>Vercel 让小程序后台的部署变得非常简单。整个过程只需要几个配置文件和一条命令，就能把本地开发的应用部署到全球 CDN 上。</p>
<p>相比传统的服务器部署，Vercel 的优势很明显：</p>
<ul>
<li>不需要管理服务器</li>
<li>自动扩容</li>
<li>全球加速</li>
<li>免费 HTTPS</li>
<li>与 Git 集成，推送即部署</li>
</ul>
<p><strong>对于个人开发者和小团队来说，这种 Serverless 的部署方式确实是个不错的选择。</strong></p>
<p>当然，Vercel 也有一些限制，比如函数执行时间限制、冷启动问题等。但对于大多数小程序后台来说，这些限制都不是问题。</p>
<p>我之前还写过一篇关于把小程序后台部署的cloudflare workers的教程，大家感兴趣也可以参考一下。</p>]]></description>
    <pubDate>Sun, 08 Mar 2026 13:26:56 +0800</pubDate>
    <dc:creator>emer</dc:creator>
    <guid>https://www.hackpro.tech/?post=2</guid>
</item>
</channel>
</rss>