缘由:
uni-app同一套代码 无法区分 微信小程序插件 和微信小程序
当前项目开发微信小程序、支付宝小程序、业务需求需要开发微信小程序插件
但是uni-app只能区分运行平台微信 支付宝 app等,无法区分插件和小程序,因此决定自己写一个条件预编译来区分。
方案思路:
参考当前条件编译模式,通过自定义脚本将不同平台的代码删除,保留当前符合条件的代码。
- 将代码编译生成新的目录
- 如何删除非当前条件的代码
- 如何匹配条件标识开始和结束
----- 优化----- - html js css json文件类型的适配
- 在当前平台需要支持其他平台
- 差量编译
- 资源文件处理
- 环境适配
思考1 --- (将代码编译生成新的目录)
目前开发代码都是在一个src目录下,通过脚本将需要打包的目录,
遍历文件 将删除后的代码写入新的目录
/*
参考系统工具,我们平时开发的内容代码,最终也是在另一个目录下运行;
系统的也是通过将当前代码经过编译 生成对应的平台的文件的代码
*/
思考2 --- (如何删除非当前条件的代码)
按行读取文件
我们可以发现,条件标识 #ifdef #end结束等 都是单独一行;
所以我们可以通过按行读取文件的内容, 判断符合#ifdef条件, 并且不是当前平台的时候,
下面的每一行开始不再写入,
直到碰到对应的结束标记,重新在开始写入.
思考3 --- (如何匹配条件标识开始和结束)
正则表达式 判断
我们可以通过正则表达式,将当前一行判断是不是符合 #ifdef 微信 || 支付宝|| 插件 等
截取出后面的部分,按照 || 分隔 判断是否包含当前条件 不包含则后面的代码需要删除
需要解决的问题就是这几步!
深度考虑
1. 当前平台条件编译有 html js css的代码
因此我们需要添加配置,将 #ifdef 、/* #ifdef */ 等 根据不同格式的统一处理,添加所有需要的平台的格式的条件标识
2. 在当前平台需要支持其他平台
因为我们的微信小程序插件 也是运行在微信小程序上的,而我们的小程序和插件是一套代码, 因此插件编译的时候 ,需要支持微信小程序的代码,
- 因此我们需要对当前平台 设置一个可以匹配其他平台的配置, 在判断是不是当前平台同时也判断一下符不符合配置的其他条件
优化体验
1. 差量编译
上面的步骤完成后 我们实际已经完成了条件编译;
但是对于文件较多的时候,每次修改一个文件,重新在编译生成的,非常耗时间,也不方便我们调试.
因此我们做了差量编译,监听处理变更的文件.
2. 资源文件处理
由于资源文件都在一个目录下,并且还有一些不需要编译的目录可以直接copy过去的,
在配置文件中 添加不需要区分条件编译的相关目录,则直接copy.
3. 环境适配
开发中 都有开发环境,测试环境,线上环境;
我们的小程序有些功能只能在上线才能测试,因此我们会发布两个不同id的小程序 一个用于测试,一个用于线上.
对于区分开发 测试 线上环境,我们处理方式 也是将
这三种环境 当做 三个平台处理,因为我们的条件平台支持配置其他条件平台;
所以 当处理其他条件平台的时候,系统会自动添加当前运行环境 到 对应平台的适配条件中,
例如 运行命令 node build.js weixin dev
则会在 weixin.coexist中 添加dev 条件 这个是在运行时添加的
weixin: {
coexist:['dev']
}
附言
下面是一些伪代码:
function 递归遍历文件夹 {
function 读取单个文件 {
for (遍历文件内容 按照行读取) {
var line = 按行读取;
if 条件编译已经开始 {
if line == 是条件编译模式,并且不包含当前平台 {
开始下一行的判断;
continue;
}
if line == #end {
结束条件编译标记,重新开始读写;
continue;
}
直接进入下一行
continue;
}
将line写入新的文件;
}
}
}
其中 在读取文件的时候 使用异步的方式,提高速度,可以缩短一半多的时间;
对于异步结束判断会延迟判断 延迟也会有一个标记,最后一个延迟到的时候,判断是否结束 ,
同时有一个文件写入的计数,最后只要判断文件是否在写入
附件源码:
直接在 precompile 下面 运行
链接: https://pan.baidu.com/s/1asmHTc2tZl3cfAmhv_kIMQ 密码: t35f