本文摘要
来自摩拜前端团队 yingye
本文从源码入手分析了 wpy 文件的编译过程,在文末还介绍了如何编写wepy plugin。
欢迎关注本系列,留言并分享 小程序开发 中的体会。
wepy 是腾讯开源的一款小程序框架,主要通过预编译的手段,让开发者采用类 Vue 风格开发。 让我们一起看看, wepy 是如何实现预编译的。先放上一张官网的流程图,后面的分析可以参考该图。
wepy-cli 主要负责 .wpy 文件的编译,目录结构如下:
编译的入口是 src/compile.js 中的 方法,该方法主要是根据文件类型,执行不同的 compiler ,比如 .wpy 文件会执行 compile-wpy.js 下的 方法。
.wpy文件拆解
compile-wpy.js 下的 方法,核心调用了 方法。
方法,主要是将 .wpy 拆解成 对象,并对其中的 template、script 做一些预处理,然后将 template、 script、 style 三部分移交给不同的 compiler 处理。
生成rst对象
通过 xmldom 获取 对象,然后遍历节点,拆解为 对象。
对象结构如下:
此外,还对 template 做了如下一些预处理:
获取文件中的 ,放入 中
获取 和 ,放入 中
compile-template
compile-template.js 中的 方法,根据 template 的 lang 值,执行不同的 compiler ,比如 wepy-compile-typescript 。编译完成后,执行 compileXML 方法,做了如下的操作:
方法: 替换 slot 内容
方法: 在 {{}} 和 attr 上加入组件的前缀,例如: ->
把自定义的标签、指令转换为 wxml 语法,例如:
compile-style
依旧先是根据 lang 值,先执行不同的 compiler ,比如 wepy-compile-less 。编译完成后,执行 src/style-compiler/scope.js 中的 方法,处理 。
这里主要是利用 add-id 的 postcss 插件,插件源码可参考 src/style-compiler/scope-id.js。根据上面的代码,打印出来的log如下:
最后,会把 由绝对路径替换为相对路径,并在 wxss 中引入,最终生成的 wxss 文件为:
compile-script
依旧先是根据 lang 值,执行不同的 compiler。compiler 执行完之后,判断是否是 npm 包,如果不是,依据不同的 type 类型,加入 wepy 初始化的代码。
接下来会执行 方法,主要是处理 。根据 文件的类型,拷贝至对应的目录,再把 中的 代码替换为 相对路径。
处理好的 最终会写入 文件中,文件存储路径会判断类型是否为 npm。
plugin
根据上面的流程图,可以看出所有的文件生成之前都会经过 Plugin 处理。先来看一下,compiler 中是如何载入 Plugin 的。
在有多个插件的时候,不断的调用 ,最后执行 。
编写plugin
wxss 与 css 相比,拓展了尺寸单位,即引入了 单位。但是设计童鞋给到的设计稿单位一般为 ,那现在我们就一起来编写一个可以将 转换为 的 wepy plugin。
从 PluginHelper 类的定义可以看出,是调用了 plugin 中的 方法。另外,只有 .wxss 中的 才需要转换,所以会加一层判断,如果不是 wxss 文件,接着执行下一个 plugin。 转换为 的核心是,使用了 postcss-px2units plugin。下面就是设计好的 wepy-plugin-px2units,更多源码可参考 github 地址( https://github.com/yingye/wepy-plugin-px2units )。
最后
本文分析的源码以 wepy-cli@1.7.1 版本为准,更多信息可参考 wepy github (即 github 1.7.x 分支,https://github.com/Tencent/wepy/tree/1.7.x )。另外,文中有任何表述不清或不当的地方,欢迎大家批评指正。
昨日的日刊是不是漏看了,给你一个传送门:
好消息:
1、可以在公众号【菜单 - 日刊】上看到所有的日刊文章模板啦
2、日刊君也开通了知乎专栏 [前端新视野]:
https://zhuanlan.zhihu.com/c_141430263
一个一天就破 *k 关注的日刊号
一个立志把质量当生命的日刊号
一个大佬们都在关注的日刊号
...
分享给喜欢学习的小伙伴吧
领取专属 10元无门槛券
私享最新 技术干货