某项目总结

年纪大了,不写项目总结总有一天会忘记的。

这次的项目似乎不能暴露是谁做的,暂时称作某项目吧。

某项目从2月初开始,因为其大型活动是在3月底四月初开始,所以原本计划是3月初上线,结果因为客户经常不睬我们,项目最后是3月中旬上线的。

这次项目因为客户不肯给钱所以PM说不用做的太细。
不过因为本人入了某教所以对此项目一腔热血,2月底就几乎把前端功能都做好了。
去掉后端功能,简单来说就是给图像加装饰。

后端是Rails,并且估算了下工时足够我玩,所以尝鲜用了 react-rails 。
项目中一共两个页面,一个DIY图片的页面,一个Twitter头像更新成功后的反馈页面。
第一个页因为要给图片加装饰,便用了 fabric.js ,一个很强大的canvas plugin,适合DIY画布。
第二个页面没啥东西,就是展示修改好的图片而已。

  1. react-rails第一次用,完全不知道会有多少坑。实际用下来感觉还是挺不错。
    缺点是必须按照文档的结构来写,不知道怎么用 redux 和 flux。
    Component Class 全部暴露在 Global 环境中,尝试过闭包 + import/export,无果。
    看了下 issue 里也有好多人提出这个问题。不过为了少折腾,所以这次没深究。
    可以将 react 模版 写在 html 里,还是挺新颖的。
    好像也可以写在 controller 里,没试过,不过不推荐。
    也许这就是传说中的 server rendering 。

    这次 component 里有个 form ,所以把 token 作为 props 传给了js。
    找了很多,这似乎是比较正规的解决方式。
    另外,因为没有用 flux , component 之间的数据传输有点麻烦。
  2. CORS单独领出来写,原因是被坑了好长时间。
    给 twitter 头像加装饰后把新头像传给 twitter 需要把 canvas 转成 base64 URI。
    因为 twitter 头像是来自其它域名的图片,所以画在 canvas 上时会出现 CORS 问题。
    twitter API 请求次数有上限, local 开发的时候用的是本地图片替代了 twitter profile image 。开发的时候也就没有注意到 cross-origin 的问题。
    到测试的时候这个问题浮现了出来,写了好几个解决方式,后来用了:

    这便给上线后埋下了祸根。
    很多文档上大多提到了只要设置 img 的 crossOrigin 属性就能解决 CORS 问题。
    但是上线后在一部分人的浏览器里出现了问题。如果是第一次访问这个页面不会有问题,但是如果在有缓存的情况下,还是会报 crossOrigin 的错误。
    后来在某个 stackflow 的帖子里找到说,crossorign 必须在图片加载完成前付给图片才有效。我只能猜测在某些情况下,因为从缓存读图片比浏览器解析DOM attribute 还快,所以导致了 crossorigin 没有生效。
    最后老实的用了 new Image() 的方法来 preload 这张唯一的跨域图片。


    另外要说下,这个 bug 我在任何浏览器任何网络任何设备上都没发再现,公司测试也是,后端开发A也是。后端开发B和PM和运维却碰到了。根据 twitter 反馈,确实有一部分人会出现这个图片 Cache 导致的问题。PM是safari下,运维是在Android Chrome下,后端开发B是Mac下任何浏览器。
    所以,至今我都不知道如何再现这个 bug 。
    当然,其实 fabric.js 支持 CORS DrawImage ,但是这次我没有用。
    因为 fabric.js 加载成功后是直接画在画布上的,没有 fadeIn 的效果。
    本来对于 react 和 fabric 不是很了解,这次就没有在 Canvas 效果上多写什么。
  3. Node.ChildNodes一如既往没有用 jQuery 和 lodash ,而是 Vanilla JS 。
    第一次用 Node.ChildNodes ,一开始以为和 jQuery 的 children() 一样。
    上线后 CORS 问题迟迟解决不了后,才偶然发现原来自己想的太简单了。
    TextNode 也是 node !
    TextNode 也是 node !
    TextNode 也是 node !
    重要的事情说三遍。
    没错,我其实还取到了很多 <code>/\s*\n/</code> 。
    我还在那里天真的 forEach ,天真的取他们的 dataset,天真的给它们绑定 onload 。
    重新把 ChildNodes 过滤了一遍。这才取到了正确的 ElementNode

    不过现在想如果想避免取到 TextNode 的话其实可以用 querySelectorAll 。

基本就是以上这些。
总结下来自己对 js / react / promise / canvas 都不是很了解。前端路还长着呢。