一个 API 设计上的失误
意识到自己的设计失误,源于同事的一次开发报错
事情回到工具库设计当初,我需要为内部封装一个浏览器环境判断库,这个库需要的功能非常简单,判断是否在某些宿主环境中打开,比如移动端、微信、微博,以及我们自己的 APP,等等,实现思路也非常简单,拿到 UA 进行分析就行了
但是在 API 设计上,我有了两个思路。思路一,导出一个方法,该方法返回一个对象,包含我们需要的数据,思路二更粗暴,直接返回对象
// 方案一
import browser from 'browser'
const { isMobile, isWeibo } = browser()
// 方案二
import browser from 'browser'
const { isMobile, isWeibo } = browser
我用了方案二,我的想法是 API 设计越简单越好,调用越方便越好,在导入库的时候,直接会去获取 navigator.userAgent
,这就有一个局限性,这个库只能运行在客户端,因为 server 上是没有 navigator.userAgent
的(但是我们可以做兼容,这个后面说)。当时我的想法是,我们的项目基本都是客户端项目,问题不大,如果是 Node 项目,不要去引这个包就行了
但是同事用在了 Nuxt 项目上。如果项目中用如上方式引入了库,打包的时候会把库分别打包到客户端和服务端的 bundle 中,这就意味着这个库会在服务端运行(因为设计是引入即执行)。我们可以临时用两个方案去解决这个问题,一是在 beforeCreate 和 created 外的其他钩子里,用 require 的方式去引这个包,保证只在客户端执行,但是我们其他包的引入方式都是用 ES6 import 的形式,这个特立独行就显的不优雅,而且没法做 tree shaking(尽管可能也不需要);另一个方案是修改库源码,兼容 Node server,当判断非客户端时候,直接返回空对象,但是这也有瑕疵,服务端也会去执行包的代码,尽管这并不需要
综上,我反思后觉得这个 API 设计是失误的,应该采用方案一,真正的核心代码运行还是交给业务方去做,其实细想,我所使用的开源库就没见过二的方式,也是有原因的
此外对于 Nuxt,我还有另外一个想法,能否客户端/服务端分别打包自己需要的代码呢?如上 browser 库只是客户端需要,服务端的 bundle 中就不用打包进去了,但是按照现在打包工具的打包方式来说,我觉得是做不到的
最后的假设,仿佛有另外一种做法,使用 Nuxt 插件,可以自定义插件作用的范围(客户端还是服务端,or both)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库