6

wepack 开源了...

 3 years ago
source link: https://zhuanlan.zhihu.com/p/356700700
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

wepack 开源了...

俺,只想跪在床上娇喘,不想隔着网线叫唤

大家晚上好,俺是大朋友132,经过不懈的努力,wepack 终于开源了

突然有种此时无声胜有声的感慨……

背景和痛点

随着大家项目复杂度的升高,基于 taro + wepack 开发小程序的方式,一层层 loader 和 plugin,将开发链路大大延长

过长的开发链路,除了打包时间变慢,更重要的是严重影响力调试,测试,维护

除此之外,case by case 的 AST 转译方式,擅自扭曲语法语义,也会很不地道的行为

今年是打包工具大乱斗的一年,vite,snowpack 等工具出一个火一个

v2-c40e0b9a0924064e14697b1bbe536d32_720w.jpg

wepack

所以我就写了 wepack

wepack 比 webpack 少了一个 b,但他们服务的业务场景大不相同,wepack 旨在专门打包微信小程序,wepack 之于小程序可以类比为 metro 之于 RN

通俗的讲,它可以将微信项目打包成可执行的 js,css 文件,但和同类工具相比,它的中心是打包而不是转译

这有很多好处:

  1. 小程序引擎

你可以将 wepack 的产物放到你们公司的 APP webview 上,这样就可以称为专属小程序系统

wepack 虽然和传统小程序引擎不同,他没有使用双线程的架构,但它使用了微前端模拟沙箱环境,这对用户而言并无大碍

过去我一直在研究小程序引擎,但是我发现双线程的模型维护成本太高了,搞来搞去到头来还不如直接跑 webview

另外,wepack 是微信小程序标准的重新实现,在实现过程中,我有机会解决一些微信残留的历史包袱

wepack 是一个更现代的小程序子集

2. 开箱即用

这也是首当其冲的,所谓开箱即用,0配置,简单说就是缩短链路,至少不能多次转译打包了

这一点也是我备受质疑的原因,很多人都告诉我,我们 webpack 用的好好的,我们连 vite 都不需要,更不需要 wepack

诚然,目前国内 90% 的项目都是 webpack 主打的,我不打算推翻任何人

只是条条大道通罗马,我更喜欢走新路线

3. 跨双端

还要一个明显的好处就是,wepack 可以跨微信和 h5 端,虽然如果只是跨端的话没必要做到这个程度,但确实跨端是一个不可争议的业务场景

这个是我接下来要努力解决的事情了,毕竟刚刚也说了,公司永远都是 业务维护先于架构设计

有意思的东西

为了写 wepack,我研究了几乎所有的打包工具,发现了许多有意思的事情,接下来我挑着说一下

  1. 面向数据结构编程

上面这张图是 wepack 的架构图,中间有一棵树叫做 ADT,通俗讲就是

我将微信整个项目用一棵树进行描述,然后使用 AST 分析每个文件,将有用信息放到这棵树上

然后其他的所有的操作,比如 tree shaking 就都可以围绕这棵树进行下去了

不会转译 AST 不会 case by case 不会扭曲语义

所以同样是编译,wepack 不会出现 taro2 那种应接不暇的情况

实际上,所有的打包工具都有类似的数据结构,比如 webpack 的 dependency graph,rollup 的 module graph 等等

所有的轮子都是面向数据结构编程,case by case 终究是不归路

2. tree shaking

在说 tree shaking 之前,先说一下常规的打包方式

传统的打包方式是利用 mapping + require 来实现的,因为需要实现一个 runtime 的函数,所以它无法被静态分析和优化

所以大家想到了一个办法,也就是作用域提升,就是将所有的函数都拍平,重命名

这样就很容易静态分析和 tree shaking 了

wepack 做的事粗粒度的 tree shaking,也就是 import 和 export 级别的,rollup 可以做到 scope 级别,terser 还会有常量传播的优化

3. module federation

MF 是 webpack5 的新 feature,你可以理解为 runtime 版本的 code splitting

import('app/a.js')
// 会被编译成
const remotes = {
  'app/a.js' : code
}
function ensure(key){
  return remotes[key]
}

原理非常简单,就是将 import() <import/> <template/> @import 这类特殊的标识编译为 ensure 函数,然后从全局 mapping 中拿代码

这个思路可真的帮了大忙,wxml 的语法糖比较乱,module federation 可以统一概括它们

4. wxml 编译器

说白了就是一个 html-parser,但我选择自己写,因为 wxml 比较骚,用现成的我不放心

和 homo 不一样,wepack 的 parser 我用了比较常规的写法,没有用 single pass

这是因为未来我可能写多个 generator,比如直接生成支付宝,百度,字节等等

对编译原理有兴趣的也可以看看

效果

比想象中的好,也比想象中的坏

好的是,简单项目需要改动的不多,也就调整一下css样式

比如这个图虫项目,就是

写的小程序,很轻松就可以转出来

但是我们公司的项目就很复杂了,对我来说是个很大的挑战

但是我必须得搞出来,因为事实就是如此,一个轮子的作用,比起服务新业务,解决历史报复才是真正的刚需

接下来我会全身心投入到公司业务中,转成功一个项目,就意味着铲平一座 shi 山

这很难,但这就是刚需

总结

说实话 wepack 我思考的比写的代码更多,哪怕现在我开源出来了,代码仍旧很不老道

我接受吐槽,但希望更多的人能够提出建设性的意见和建议

因为这就是开源的意义,wepack 的模型目前没人做,所以它的架构并不稳定,需要大家一起探索

因为我还是要处理公司业务为主,所以对于架构的调整思路,只能寄希望于外界反馈啦!

以上,望天,我有写了这么多

最后再放一次连接的啦:ctripcorp/wepack

欢迎 star,欢迎 discusssions 刷屏!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK