从零开始构建一个现代化前端项目:一个被裁外包仔的实战复盘

产品说很简单
2026-01-13 22:47
阅读 1025

作者:老K,前大厂前端,现深圳南山自由接单人。房租3500,猫粮每月120,靠React和咖啡续命。


开头:凌晨三点的泡面与焦虑

去年十月的一个周五晚上,我坐在南山区白石洲一间不到15平米的出租屋里,面前摆着一碗已经凉透的康师傅红烧牛肉面。窗外是深南大道永不熄灭的霓虹,而我的MacBook屏幕上,是一封HR发来的“优化通知”邮件。

“因组织架构调整……感谢你过去两年的贡献……N+1已打款……”

我盯着那行字看了足足十分钟,脑子里一片空白。那时我才意识到,所谓“大厂光环”,在裁员潮面前,不过是一张薄纸。

更扎心的是,第二天早上老婆(对,我结婚了)醒来第一句问我:“下个月房贷怎么办?”

那一刻,我真的慌了。但慌完之后,只能硬着头皮往下走——于是我注册了几个外包平台,开始接单。第一个客户,是个做区块链钱包的小创业公司,老板姓李,在腾讯大厦楼下约我喝了一杯瑞幸。

他说:“我们要做一个Web3的DApp,前端用React,UI要炫一点,最好下周就能看Demo。”

我差点一口咖啡喷出来——下周? 但想到银行卡余额只剩8000块,我还是点了点头。

于是,这个“从零开始构建一个现代化前端项目”的故事,就这么仓促地开始了。


一、不是所有“从零开始”都叫脚手架

很多人以为“从零开始”就是 npx create-react-app 走起。但现实哪有那么简单?

李老板的需求很模糊:“我们要一个像MetaMask那样的界面,用户能连钱包、查余额、转账,还要能看链上交易记录。”
我问他:“用哪条链?”
他说:“先做以太坊吧,后面可能加Polygon。”
我又问:“要不要支持多链切换?”
他想了想:“当然要啊,不然怎么显得我们专业?”

我内心OS:这哪是做DApp,这是要做Web3版支付宝啊!

但没办法,接了单就得干。我花了整整一个周末,在GitHub上翻了十几个开源钱包项目,最后决定——不直接抄,但借鉴架构

我最终选择的技术栈如下:

  • React 18 + TypeScript(必须的,类型安全能救命)
  • Vite(比Webpack快太多,开发体验直接拉满)
  • Tailwind CSS(快速出UI,省得写样式到秃头)
  • Ethers.js(连接以太坊的标准库)
  • Zustand(状态管理,比Redux轻量太多)
  • Wagmi(专为Web3设计的React Hooks库,真香)
  • ESLint + Prettier + Husky(代码规范不能少,不然review时会被客户骂死)

光是搭环境就折腾了两天。Vite配置别名、Tailwind集成、Wagmi初始化……每一个环节都有坑。比如Wagmi默认用EIP-1193标准,但有些老钱包(比如某些国产钱包)不完全兼容,得手动处理Provider。

这时候我才明白:所谓“现代化前端项目”,不是堆砌最新框架,而是用合适的工具解决实际问题。


二、面试题挑战?不,是生产环境挑战

有趣的是,在开发过程中,我居然遇到了好几个“前端面试题”。

比如,有一次李老板突然问我:“为什么用户连上钱包后,页面刷新就断开了?”

我心想:这不就是经典的“状态持久化”问题吗? 面试官最爱问:“如何在页面刷新后保持登录状态?”

但在Web3场景下,问题更复杂——你不能简单存个token,因为钱包连接依赖于window.ethereum这个注入对象,而它只在钱包扩展存在时才有效。

我的解决方案是:

  1. 用Zustand存储用户地址和链ID
  2. 页面加载时,检查是否已有地址
  3. 如果有,尝试重新激活Wagmi的Connector
  4. 如果失败(比如用户卸载了钱包),则清空状态

代码大概长这样:

// stores/walletStore.ts
import { create } from 'zustadt';
import { getAccount, switchChain, disconnect } from '@wagmi/core';

export const useWalletStore = create((set) => ({
  address: null,
  chainId: null,
  connect: async () => {
    const account = await getAccount();
    set({ address: account.address, chainId: account.chainId });
  },
  reconnect: async () => {
    try {
      const account = await getAccount();
      if (account.address) {
        set({ address: account.address, chainId: account.chainId });
      }
    } catch (e) {
      // 钱包未安装或未授权
      set({ address: null, chainId: null });
    }
  }
}));

然后在App.tsx里:

useEffect(() => {
  const storedAddress = localStorage.getItem('walletAddress');
  if (storedAddress) {
    useWalletStore.getState().reconnect();
  }
}, []);

你看,面试题从来不是为了刁难你,而是真实世界的问题简化版。只是现实中,你还要处理MetaMask、Coinbase Wallet、Trust Wallet等各种兼容性问题。

有一次测试时,我发现Trust Wallet在移动端Safari里根本打不开dapp——后来才知道它不支持window.ethereum,得用WalletConnect。于是又加了一套连接逻辑。

那一刻我真想对着屏幕喊一句:“求求你们统一标准吧!”


三、区块链不是噱头,是新的交互范式

很多人觉得“区块链+前端”就是贴个标签,但真正做起来才发现,整个交互逻辑都变了

传统Web应用,数据在服务器;而DApp的数据在链上,前端只是“读取器+触发器”。这意味着:

  • 所有操作都是异步且不可逆的(交易一旦发送,无法撤回)
  • 用户需要支付Gas费(所以你得实时显示预估费用)
  • 网络可能拥堵(交易可能卡几小时)
  • 链上数据查询慢(得用The Graph或Alchemy加速)

我在做“交易历史”功能时,最初直接调ethers.js的provider.getHistory(),结果发现一次请求要5秒+。用户肯定骂娘。

后来改用Alchemy的API,配合React Query做缓存,体验才好起来。

更头疼的是错误处理。比如用户余额不足,或者Gas设置太低,ethers.js会抛出各种cryptic error message(比如“insufficient funds for gas * price + value”)。普通用户根本看不懂。

于是我写了一个错误映射表:

const ERROR_MESSAGES = {
  'insufficient funds': '余额不足,请检查ETH余额',
  'nonce too low': '交易已被替换,请刷新页面',
  'gas price too low': 'Gas费用过低,建议提高'
};

前端不再是“展示层”,而是用户与去中心化世界的翻译官。这让我重新思考前端的价值——我们不只是切图仔,更是用户体验的守门人。


四、外包的真相:没有需求文档,只有微信语音

说实话,做外包最痛苦的不是技术,是沟通。

李老板从来不写PRD,所有需求都在微信里说。有一次半夜11点,他发来一段60秒语音:“老K啊,我觉得转账页面那个按钮颜色不够‘科技感’,能不能改成那种蓝紫色渐变?就像币安那样。”

我默默打开Figma,把#3B82F6改成#8B5CF6,心里默念:“我是艺术家,我是用户体验设计师,我不是调色盘……”

还有一次,他说:“能不能加个功能,让用户一键把NFT挂到OpenSea上?”
我:“……OpenSea不开放挂单API。”
他:“那别的平台呢?”
我:“都不开放。”
他:“那你想想办法嘛。”

外包的潜规则:客户永远觉得“技术能搞定一切”,而你得在“做不到”和“收更多钱”之间找平衡

最后我折中做了个“导出元数据”功能,用户可以把NFT信息下载下来,手动上传。收了他额外3k,勉强回血。


五、转机:从接单到建立自己的产品思维

做到第三周,项目基本成型。李老板很满意,还介绍了一个做DeFi的朋友给我。更重要的是,我自己开始有了想法

我发现市面上很多Web3前端都做得特别丑,交互反人类。为什么不做一个“前端模板库”,专门给DApp开发者用?

于是我在业余时间,把项目里的通用组件抽离出来:钱包连接按钮、链切换器、交易状态提示、Gas费用估算器……打包成一个npm包,叫web3-ui-kit

没想到发到GitHub后,居然有人star,还有人提issue。虽然现在只有200+ stars,但至少证明——我不是在重复造轮子,而是在解决真实痛点

这也让我意识到:外包不是终点,而是跳板。通过接不同项目,我能快速积累垂直领域经验(比如Web3),再把这些经验产品化,形成自己的护城河。


六、写给同样在挣扎的你

如果你也在经历裁员、焦虑、接单维生,我想说几句掏心窝的话:

  1. 别怕从小项目开始。我第一个外包单才8k,但换来的是Web3实战经验。
  2. 技术是手段,不是目的。客户不在乎你用React还是Vue,只在乎功能能不能跑。
  3. 把每次“救火”变成知识沉淀。遇到问题就记下来,写成博客或组件库,长期看是资产。
  4. 保持输出。哪怕只是朋友圈发一句“今天搞定了Wagmi多链切换”,也是个人品牌的积累。

我现在月收入不稳定,有时2w,有时1w5,但至少不用看老板脸色。上周刚带老婆去吃了顿海底捞——她说:“比你以前加班吃泡面强多了。”


结尾:前端不死,只是进化

从大厂格子间到白石洲出租屋,从CRUD工程师到Web3全栈外包仔,这一路跌跌撞撞,但也看清了很多事。

React会过时吗?可能会。区块链是泡沫吗?也许。但只要用户还需要界面,前端就有存在的价值

区别在于,以前我们对接产品经理,现在我们对接智能合约;以前我们优化首屏加载,现在我们优化交易确认速度。

技术在变,但解决问题的心没变。

所以,别被“现代化”吓住。所谓现代化项目,不过是用今天的工具,解决今天的问题。

而你我,都在路上。


后记:这篇文章写完那天,我又接到一个新单子——用React做NFT铸造平台,预算3w。我回了个“OK”,然后关掉电脑,牵着狗下楼散步。深圳的晚风有点热,但心里踏实。

评论 0

最热最新
暂无评论
产品说很简单Lv.1
0
影响力
0
文章
0
粉丝