“代码的半衰期”
在 JavaScript/TypeScript 生态中,这个半衰期极短,一年前的项目在今天确实可能因为依赖冲突(Dependency Hell)而无法直接运行。
这个问题非常大,而且是我学习项目的第一个问题,并且我也没有很好的重视这个问题.
换作一个顶级有经验的开发者,他们的核心目标不是“复刻一个一模一样的 App”,而是“掌握其架构思想并用当前最佳实践实现它”。
思考明确自己的需求
我非常喜欢学习哪些具有新颖技术框架的项目,它们使用了很多酷炫的技术栈,能让我学到很多东西,事实也正是如此.
但我从来都对自己的需求感到模糊; 我既想要复刻和原项目中一模一样的功能,又想使用现在所有依赖的最新版本. 这种想法带来了极大的技术债务和实践风险.
所以我思考了自己对于项目的学习策略
两种截然不同的学习策略
A 路径:复刻路线(快速跑通,专注于业务逻辑)
如果我只想看作者怎么写业务代码,那就不要尝试升级。
- 直接复制作者源码中的 package.json,并去掉版本号前的 ^ 或 ~(将其改为固定版本)。
- 强制安装: 如果遇到 Peer Dependency 报错,使用 pnpm install —no-frozen-lockfile 或 npm install —legacy-peer-deps。这会强制安装,跳过版本检查。
之后就按照视频或项目作者的思路,一步步去跟着实现
B 路径:重构路线
这是一个非常值得深思的路径,它不亚于大量时间去进行投资.我会故意安装最新的版本依赖,然后硬着头皮去实现它
在这个过程中要着重注意这两点:
- 看文档而不是看视频: 例如,当视频里用到 Better Auth 的某个 API 报错时,立即去翻阅其官方文档的 Migration Guide。
- 理解 Breaking Changes: 学习这段时间里,这个工具发生的进化.例如 Drizzle 的推断类型(Inference)可能变了,这种“解决报错”的过程才是真正提升技术品控的时候。
不要无脑看视频
不要把视频当成“听写课”,而要当成“架构拆解课”。 核心要搞懂自己的需求,之后学习架构拆解:
- 数据流向(Data Flow): 观察作者是如何从前端请求到后端 Server Side,再到数据库的。中间经历了哪些层?(例如:UI -> Nuxt Server API -> Drizzle -> DB)。
- 状态管理策略: 作者是用 useState 还是 Pinia?为什么在这里要用 watch 而不是 computed?
- 组件拆分粒度: 观察作者是如何把 MapLibre 封装成一个可复用的 Vue 组件的。
- 解决问题的思维: 重点看作者在遇到 Bug 时是如何调试的(看控制台报错、网络请求、还是打 log)。
吃亏后的经验
-
先不要新建文件夹,起脚手架,然后边看边写,先跑通 Demo,再写自己的: 先下载作者的源码,尝试在本地跑起来(哪怕用 —legacy-peer-deps)。
-
善用 AI 辅助:当你遇到版本冲突报错时,把你的 package.json 和错误信息丢给 AI(如 Claude 3.5 或 GPT-4),询问:“这是由于哪个包的对等依赖冲突引起的?我应该如何调整版本号?”
-
不要在配置上耗费超过 20% 的时间: 如果一个依赖调了一小时都过不去,直接替换它。比如 MapLibre 调不通,你可以先用最简单的 Leaflet 或者干脆先用一个
占位,先把核心逻辑(增删改查)写完。
小总结
项目成为半成品我很难受,依赖冲突问题很难解决
我总不能直接在github发issue去催作者去更新仓库,这样违背了开源精神,而且很不道德很自私.
为避免下次吃亏,我建议我自己:
1. 多使用git进行版本管理,实现单一功能后直接提交,push,pull,merge.
2. 先列feature list, 完成一个feature就勾一个
3. 技术是不会永葆青春的, 在JS/TS生态下,半年就会变一次. nodejs版本一更新,整个世界都变了.一年前的项目就像是一年前的新闻,重点要看它的实现逻辑,而不是看它的API
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
