You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importpostcssfrom'postcss';importscopeIdfrom'./scope-id';exportdefaultfunctionscopedHandler(id,content){console.log('id is: ',id)console.log('css content is: ',content)returnpostcss([scopeId(id)]).process(content).then(function(result){console.log('css result is: ',result.css)returnresult.css}).catch((e)=>{returnPromise.reject(e)})}
wepy 是腾讯开源的一款小程序框架,主要通过预编译的手段,让开发者采用类 Vue 风格开发。 让我们一起看看, wepy 是如何实现预编译的。先放上一张官网的流程图,后面的分析可以参考该图。
wepy-cli 主要负责 .wpy 文件的编译,目录结构如下:
编译的入口是 src/compile.js 中的
compile()
方法,该方法主要是根据文件类型,执行不同的 compiler ,比如 .wpy 文件会走 compile-wpy.js 下的compile()
方法。.wpy文件拆解
compile-wpy.js 下的
compile()
方法,核心调用了resolveWpy()
方法。resolveWpy()
方法,主要是将 .wpy 拆解成rst
对象,并对其中的 template、script 做一些预处理,然后将 template、 script、 style 三部分移交给不同的 compiler 处理。生成rst对象
通过 xmldom 获取
xml
对象,然后遍历节点,拆解为rst
对象。rst
对象结构如下:此外,还对 template 做了如下一些预处理:
pug
预编译import
,放入rst.template.components
中props
和events
,放入rst.script.code
中compile-template
compile-template.js 中的
compile()
方法,根据 template 的 lang 值,执行不同的 compiler ,比如 wepy-compile-typescript 。编译完成后,执行 compileXML 方法,做了如下的操作:updateSlot
方法: 替换 slot 内容updateBind
方法: 在 {{}} 和 attr 上加入组件的前缀,例如:{{width}}
->{{$ComponentName$width}}
compile-style
依旧先是根据 lang 值,先执行不同的 compiler ,比如 wepy-compile-less 。编译完成后,执行 src/style-compiler/scope.js 中的
scopedHandler()
方法,处理scoped
。这里主要是利用 add-id 的 postcss 插件,插件源码可参考 src/style-compiler/scope-id.js。根据上面的代码,打印出来的log如下:
最后,会把
requires
由绝对路径替换为相对路径,并在 wxss 中引入,最终生成的 wxss 文件为:compile-script
依旧先是根据 lang 值,执行不同的 compiler。compiler 执行完之后,判断是否是 npm 包,如果不是,依据不同的 type 类型,加入 wepy 初始化的代码。
接下来会执行
resolveDeps()
方法,主要是处理requires
。根据require
文件的类型,拷贝至对应的目录,再把code
中的require
代码替换为 相对路径。处理好的
code
最终会写入js
文件中,文件存储路径会判断类型是否为 npm。plugin
根据上面的流程图,可以看出所有的文件生成之前都会经过 Plugin 处理。先来看一下,compiler 中是如何载入 Plugin 的。
其中,config.plugins 就是在 wepy.config.js 中定义的 plugins。让我们来看一下
PluginHelper
类是如何定义的。在有多个插件的时候,不断的调用
next()
,最后执行done()
。编写plugin
wxss 与 css 相比,拓展了尺寸单位,即引入了
rpx
单位。但是设计童鞋给到的设计稿单位一般为px
,那现在我们就一起来编写一个可以将px
转换为rpx
的 wepy plugin。从 PluginHelper 类的定义可以看出,是调用了 plugin 中的
apply()
方法。另外,只有 .wxss 中的rpx
才需要转换,所以会加一层判断,如果不是 wxss 文件,接着执行下一个 plugin。rpx
转换为px
的核心是,使用了 postcss-px2units plugin。下面就是设计好的 wepy-plugin-px2units,更多源码可参考 github 地址。最后
本文分析的源码以 wepy-cli@1.7.1 版本为准,更多信息可参考 wepy github (即 github 1.7.x 分支)。
欢迎各位关注我的Blog,正文以issue形式呈现,喜欢请点star,订阅请点watch~
The text was updated successfully, but these errors were encountered: