阅读 7714
某大型电商满一年的时候,我离职了

某大型电商满一年的时候,我离职了

(文章做了脱敏,重发一次)

我是 2020 年 10 月 22 入职的某大型电商,到明天就满一年了。但也在这几天,我提了离职。其实做出这个决定我也很纠结,放弃了很多东西,但我还是决定走了,这篇文章就来讲一下为什么。

回顾某公司一年

某公司跨端引擎团队做什么

我入职的是跨端引擎团队,某公司有自己的跨端引擎,也就是通过 c++ 给 v8、javascript core 扩展了很多 api,这些 api 由安卓、ios 分别实现,包括渲染 dom 和 css,使用各种设备能力的 api。

因为基于 js 引擎实现了 w3c 标准的 dom api 和 css,那跨端引擎上就可以跑 html、css、js 代码,通过它们组织逻辑,然后由 natvie 实现渲染和交互。

这之上还有一个类似 react 的前端框架,是我们修改以后的,最终渲染用的 dom api 是跨端引擎提供的那些。

这样,业务线就可以通过一个个 react 组件来组织页面,通过各种跨端引擎提供的 api 完成页面交互和业务逻辑。

这个跨端引擎上跑的代码是有自己的一套规范的,业务线写代码会用 less、typescript、es next 等语言,然后转成跨端引擎支持的写法,所以需要自研编译器来做这种转换。

我们基于 babel、less compiler 实现了编译器,递归的分析依赖,编译每一个文件,然后打包到一起。我们并不需要 webpack 一样的 chunk 分组,因为不是浏览器平台,只需要压缩到一块就行。打包的产物是一个二进制文件,叫做 bundle。

编译只是让源代码能够在跨端引擎上跑起来,但跑起来之后会有日志、报错等信息,会需要做 dom、css 的调试、 js 的 debugger 等,这就需要自研调试工具,我们基于 chrome devtools protocol 实现了自己的调试工具。

编译、调试都是和写代码强相关的,所以又基于 vscode 定制了 ide,集成自研编译器、自研调试工具等,也实现了很多写代码相关的 vscode 插件,比如路径提示,js、css 的智能提示等,因为跨端引擎支持的样式和 js api 都是不一样的,需要自己实现。

跨端引擎上的代码是一个个 bundle 的形式存在的,而 bundle 和 bundle 之间会有依赖,因为运行平台是自研跨端引擎,不支持 node_modules 那一套,所以自研了依赖管理工具。包括通过一个 bundle.json 声明依赖,递归的下载依赖,全局的缓存等。

此外,跨端引擎提供的各种 api 对于 c++、安卓、ios、文档都要保持统一,怎么保证统一呢?我们是通过 ts 作为 dsl 来描述文档和接口,然后编译成 java、oc、markdown 等,通过这种方式完成了多端 api 还有文档的的统一、可编译。

除了这些,还有依赖分析工具,分析所有跨端引擎相关的源代码,包括安卓、ios、c++、js 代码,提取各种数据供分析。

跨端引擎是 c++、安卓、ios 负责维护的,而编译器、ide、调试工具、依赖管理工具、多端 api 和文档统一工具、依赖分析工具都是我们前端同学维护的。我入职这一年就在维护这些。

我这一年做了什么

其实仔细一看就会发现,扩展 js 引擎、源码到源码的编译、ts 转多端代码和文档、依赖分析等都和编译技术强相关,这一年我在前端领域的编译技术方面的提升特别大。

我做了编译器的 sourcemap 的统一:

之前编译的每一步都是割裂的,也就是每一步都是 js/ts 代码 parse 成 AST,转换成新的 AST,再生成 js 代码和 sourcemap 这样来一遍,但没有对每一步产生的 sourcemap 做关联,这就导致了最终跑在跨端引擎的代码并不能通过 sourcemap 映射到源码。

我修改了整个编译流程,每一步都把 AST 传递下去,这样修改完一遍之后再生成 sourcemap,这时候的 sourcemap 就是能映射到源码的,可以直接调试源码。

我做了依赖安装工具的升级:

最初的依赖安装工具是分析 bundle.json,递归解析依赖然后下载到 xxx_modules 目录下,并没有做全局的缓存,这就导致一个依赖的多次下载耗时是一样的。而且我们会修改下载下来的依赖 bundle,多个项目的同个 bundle 需要分别做修改,不能只修改一份。

我做了全局缓存,第一次下载会把依赖缓存到全局目录,然后复制到本地,后续下载该依赖直接从缓存拿,提升下载速度。我做了依赖提升到父级目录,然后 link 到本地,这样多个项目修改的是同一份 bundle。

我做了 css 的智能提示和颜色预览:

跨端引擎支持的 css 是 w3c 标准的子集,而且也有不一样的地方,业务开发同学需要经常查文档,一不小心就写错了,受这些影响,写 css 的效率是不高的。

于是我做了编译器的 css lint 功能,可以在编译期间检查出错误,后来想,为什么不提前到写代码的时候呢?于是又做了一个 vscode 插件,基于 language service protocol 实现了语言服务,支持 css 的提示、错误检查、hover 时展示文档,这样免去了查文档。还做了一个颜色预览的插件,给我们支持的一些颜色常量直接展示颜色,比较直观。

我做了 api 和 文档生成工具的升级

我们是通过 ts 的 namespace、module、function 等语法描述接口,然后编译成 java、oc、markdown 等的文件来做多端 api 和文档统一的。我们做了一个命令行工具,解析配置文件指定的 ts,对 AST 做一系列分析,之后生成各种代码和文档。

我扩展了语法的支持,实现了 enum、interface、class 等语法的解析,使接口描述方式更多样。修改了 markdown 文档的格式,使之更易读。还做了本地预览功能,可以本地生成 markdown 来看效果,之前是不支持的。

其它

这一年主要是做这些,当然还有其余的一些功能,编译器的、ide的、等等。其实一年下来,我对前端领域的编译相关技术,包括 babel、typescript、postcss、eslint、terser 等都有了比较深的掌握,对 node 也更得心应手。

除了工作以外,我还写了 《Babel 插件通关秘籍》 的小册,去早早聊、字节、掘金、华为等做了一些分享,创立了“神光的编程秘籍”的公众号,写了很多原创文章。也定下三年内写一本前端编译的书的打算。

离职原因

其实,我对现在的工作内容和学习状态是非常满意的,但我还是选择这个时候离职了。

为什么呢?这就涉及到了一个支线剧情。

二月份的时候,我在知乎问了一个问题:前端转 c++ 编译器开发靠谱不?因为当时发现自己对编译技术很感兴趣,但是因为本身离这个比较远,不知道该怎么过渡。

得到了很多大佬的建议,其中有华为的杨海龙大佬。我之前也去华为的 deeplang 社区做过分享,讲前端领域的编译技术。然后也加了编程语言实验室负责人的微信。

就在最近,华为的编程语言实验室那边联系我说那边开放了一些岗位,问我是否感兴趣。

我想了下,如果我继续在某公司待下去,后面的故事应该是这样的:

陆续写了 eslint、typescript 源码、postcss 等小册,写了 vscode 插件小册,两年后写了一本前端编译的书。工作上对 vscode、编译相关工具、调试相关工具更加熟悉了,做了很多重大功能,然后成功晋升 p7,在社区也积累了一定的影响力。

这些是确定性很强的。

如果去华为,有这样三点不一样:

  • 去中国最顶尖的编程语言和编译器团队,能够大幅提升编译相关技术的理解和掌握,除了一直做的源码转源码的转译器的小打小闹,还能深入解释器、编译器等技术。这些在某公司是接触不到的。

  • 可以深入 c++ 等几门编程语言,自己学和在公司里写相关代码是不一样的,那边有场景可以深入使用 c++,可以转型成 c++ 工程师。

  • 那边做的也是编译的事情,虽然估计不是写 js 代码,但思想不会差很多,这样我打算写的前端编译相关的小册和书并不需要丢下,可以继续搞。

但是去华为是不确定性很强的。

先不说我能不能顺利通过算法面试,顺利去了的话也不一定能够干好,而且那边团队很多硕士博士,很多国内外顶尖大牛,我去了大概率只是一个小透明。

但是,我还是打算抛弃在某公司的未来,去华为探索新的可能性,人生就是要有一些不确定才精彩,不是么?

所以,我在某大型电商一年的时候,离职了。

未来

后续公众号会写一些 c++,写一些编译的内容,这些和前端的关联性不大,但我会尽量和前端关联起来写,也会尽量写的通俗易懂一些。感兴趣的同学可以继续关注。以后我就不恰饭了,专心写技术文章了,因为总感觉突然转型对公众号粉丝不太负责。

这就是我这一年的某公司经历和我离职的原因。

站在 2021 年的 10 月 20 往前看,未来依然还是充满着不确定性,但也充满了希望,继续加油吧。