我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程

2,170 阅读4分钟

大家好,我是程普。

前段时间,我发布了第一个出海产品 PH Copilot,是一个基于 Plasmo 开发的 Chrome 插件和 Next.js 开发的落地页与服务端的产品。

因为我之前围绕 Next.js 生态圈做了一些开源项目,使用过 next-auth、Lemonsqueezy、prisma 等技术栈,这一次就想尝试了一些没用过的技术栈,因为只有这样我接下来才有文章可写。

等开发完成后,我发现这一路学到的知识和踩过的坑,不是几篇零散的博客文章可以讲好的,所以我决定写一份系统性的教程,把 PH Copilot 的开发过程和使用的技术方案完整记录下来。于是就写了这套 「Chrome插件全栈开发实战」 教程。

这套教程包含 Chrome 插件开发和 Next.js 全栈开发的知识,教你最适合新人独立开发者的出海技术栈组合,帮助你快速学习、落地一套全栈出海工具。

menu.webp

教程地址:weijunext.com/article/lea…

教程包含图文教程、一份 Chrome 插件源码和一份 Next.js SaaS 全栈源码。

技术栈组合

教程和源码包含的主要技术知识:

  • Plasmo - Chrome 插件开发

    • 简化开发流程:Plasmo 框架基于 React,让我们可以用 React 的开发习惯来开发 Chrome 插件。
    • 热加载支持:开发效率得到显著提升,无需手动刷新插件。
    • TypeScript 友好:Plasmo 有完善的类型支持。
  • Next.js - 全栈开发落地页与服务端

    • 全栈解决方案:前后端使用同一种语言(JavaScript/TypeScript)。
    • SEO 友好:服务端渲染(SSR)和静态站点生成(SSG)有利于搜索引擎优化。
    • 快速部署: Vercel 平台一键部署,省去繁琐的服务器配置。
  • Firebase - 授权和数据库应用

    • 快速启动:无需搭建复杂的后端架构。
    • 实时数据库:让我们的数据可以更快获得更新。
    • 免费起步:慷慨的免费额度,让我们在产品验证阶段几乎不产生成本。
  • Paddle - 支付功能集成

    • 在 LemonSqueezy 进一步限制国内用户使用的情况下,Paddle 成了最适合国内独立开发者使用的支付网关
  • AI 对话功能开发

    • 至少支持两种 AI SDK

对于国内独立开发者而言,这个技术栈组合最具性价比:

  • 低起步成本:在起步阶段不需要担心服务端资源的消耗和部署的成本
  • 全栈掌控:作为独立开发者,我们可以完全掌控产品的每个环节,从前端到后端,再到AI集成
  • 专注核心业务:这些工具和服务帮我们处理了大部分底层细节,让我们能更专注于核心业务逻辑和用户体验的优化。

这套技术栈组合非常适合用来快速构建、验证和扩展 SaaS 产品。

我想说说这套源码和教程的价值

为了写这份教程,我对每一个功能进行 code review 和代码优化,然后编写开发教程,整个过程花费了3周。

教程从实践角度出发,从0开始构建项目、搭建 Chrome 插件模板、开发功能模块,每一个步骤都单独讲解,可以帮助你渐进式学习。

源码包含 Chrome 插件端和 Next.js 端两份代码,其中 Next.js 端包含落地页和服务端功能,所有核心功能做了模块化设计,你不仅可以获得源码,还能潜移默化学会专业的代码设计方式。

我把插件端的文件夹结构导出了,你可以从中看出模块化设计程度:

// 插件端代码结构(仅展示src部分)

ph-copilot-dev-guide
├─ src
│  ├─ background
│  │  ├─ firebase
│  │  │  ├─ authService.ts
│  │  │  ├─ config.ts
│  │  │  ├─ index.ts
│  │  │  ├─ tokenManager.ts
│  │  │  └─ userService.ts
│  │  ├─ aiResponseHandler.ts
│  │  ├─ index.ts
│  │  ├─ messageHandler.ts
│  │  ├─ sendMessageToSource.ts
│  │  ├─ storageManager.ts
│  │  └─ updateChecker.ts
│  ├─ components
│  │  ├─ LanguageSwitcher
│  │  │  ├─ LanguageContext.tsx
│  │  │  ├─ index.tsx
│  │  │  ├─ translations.ts
│  │  │  └─ useTranslation.ts
│  │  └─ ui
│  │     ├─ avatar.tsx
│  │     ├─ button.tsx
│  │     ├─ card.tsx
│  │     ├─ popover.tsx
│  │     ├─ select.tsx
│  │     ├─ toggle.tsx
│  │     └─ tooltip.tsx
│  ├─ contents
│  │  ├─ components
│  │  │  ├─ ContentCommentGenerator.tsx
│  │  │  ├─ ContentOverviewGenerator.tsx
│  │  │  └─ CopilotTools.tsx
│  │  ├─ hooks
│  │  │  ├─ useDOMObserver.ts
│  │  │  └─ useUrlChangeListener.ts
│  │  ├─ styles
│  │  │  └─ content.css
│  │  ├─ utils
│  │  │  └─ constants.ts
│  │  └─ index.tsx
│  ├─ lib
│  │  ├─ constant.ts
│  │  ├─ prefixByEnv.ts
│  │  ├─ useProductDetails.ts
│  │  └─ utils.ts
│  ├─ popup
│  │  ├─ components
│  │  ├─ hooks
│  │  ├─ styles
│  │  ├─ utils
│  │  └─ index.tsx
│  ├─ sidepanel
│  │  ├─ components
│  │  │  ├─ CommentCard.tsx
│  │  │  ├─ Header.tsx
│  │  │  ├─ OverviewCard.tsx
│  │  │  └─ UserInfoCard.tsx
│  │  ├─ hooks
│  │  ├─ styles
│  │  ├─ utils
│  │  └─ index.tsx
│  ├─ store
│  │  ├─ firebaseAuthStorage.ts
│  │  ├─ useCommentLength.ts
│  │  ├─ useLanguageStorage.ts
│  │  └─ useUserData.ts
│  ├─ types
│  │  ├─ product.ts
│  │  └─ user.ts
│  └─ style.css

懂的人都知道这里面门道有多深。(这是一个梗,勿喷)

总结

这篇文章也算本系列技术分享的总述,接下来我会陆续在掘金分享本次开发的技术经验和心得,欢迎大家关注我的掘金