大概是一个多月前的事。一个之前合作过的人在微信上找我,说他朋友有个小店要改,需求换过好几轮了,想加个东西。问我接不接,我说接。
然后他让我给个价。我当时没多问细节,参考了一下以前听别人报过的价,报了个数。过了一会他回我:行,可以。
就两个字。我盯着屏幕看了半天,心里咯噔一下,觉得报低了。
后来证明确实低了。
那店是个 Shopify 的店,改的是结账页旁边那个算运费的小功能。用户选完地址以后,前端要调一个接口把运费算出来,显示在结账按钮上面。听起来很简单对吧,半天的事。我当时也是这么估的。
真正的坑不在功能本身,在于怎么把这脚本塞进 Shopify 的结账页。它那个页面是外部控制的,脚本执行顺序你说了不算,只能在 app embed 那块挂一个 script tag。我第一次写完,打开页面,啥都没有。打开控制台,报错:Cannot read properties of undefined (reading 'render')。查了下,意思是脚本跑得太早,那个接口对象还没建出来,你就去调它。
这不就典型的加载时机问题。然后我折腾了一下午,什么 defer、DOMContentLoaded、window.onload,全试了一遍,服务器上那个脚本还是不按我想的顺序跑。晚上十点多,我实在不行了,把报错贴给 AI,让它用中文讲讲这个到底咋回事。
它解释了一大段,让后用 window.addEventListener('load', ...) 包一层。我试了——还是不行。
我仔细对着它给的代码和官方文档看了一遍,发现它给的方案里有个变量名是错的,它写的是另一个插件包里的变量,跟我的根本不是同一个东西。这个就很坑。AI 大恩人,但也得查。
后来真正解决的问题,不是技术,是需求。我熬到十一点半,困得不行,把那家店的前台点开看,发现用户不选地址的时候根本没有运费那一栏,选完了才出现。那我直接把脚本改成在用户选完地址之后再初始化,就根本不用管加载顺序了。就那么一行判断的事。我前面一晚上都在想怎么让它提前执行,方向整个搞反了。
回去看那个报价,光查文档加试错就占了一半时间,后面那边又补了两个小改动,算下来时薪大概是……不聊这个了,说多都是泪。
不过也不全是坏事。至少 Shopify 那块的几个坑我是记住了,下次再有这种活我可知道得先问清楚 scope 再报价。报完价再扩需求的,都是血泪教训。
今日单词:scope,范围。见过它七八回了,这回终于扎进脑子里了。