)
1.前言官方文档中对于这部分内容介绍比较少从我能够为了这部分内容单独开一章就可以看出我认为这部分内容非常重要。我们平时测试功能可以将所有代码写在一个文件中但是真正的脚本开发过程中会有ui页面代码和逻辑代码一般情况下会分成两个或者多个文件。在autojs中一个程序只能有个主入口其他部分的代码可以看做成模块。模块整体架构类似于树形但是又有所不同主入口相当于数据根然后其他模块直接或者间接连接在树根主入口程序上。了解树形结构的都知道树形中不能出现环在模块上可以理解为A模块引入了B模块B模块就不能引入A模块了。在树形中每个节点只允许一个父级但是在模块引入过程中一个节点可以允许多个父级。这就是为什么我说模块整体架构类似于树形又有所不同。但是有种特殊情况A模块会用到B模块的内容B模块中又会用到A模块的部分内容这个怎么办其实有很多种方式方式一直接复制所需A模块的内容粘贴到B模块一份方式二新建一个C模块存放A模块和B模块的公共部分然后A模块和B模块均引入C模块方式三将所需A模块的内容加到全局中B模块通过调用全局来使用。这三种方式有各自的使用场景如果公共部分比较少并且使用模块也比较少退浆使用方式一如果公共部分比较多并且使用的模块比较多推荐使用方式二如果脚本开发已经基本完成增加部分功能时用到了公共部分推荐使用方式三。我们可以看出方式一是最笨的一种方式会导致代码冗余但是执行效率反而最高方式二是最正式的处理公共部分的方式但是使用过多反而会影响执行效率增加代码阅读难度方式三是一种介于两者之间的方式在不改变架构的情况下完成功能但是使用过多会占用大量内存。上面只是介绍各种方式的优缺点真正使用过程中使用哪种方式都不影响那种“使用过多”触发的缺点很难出现大家可以放心使用。我后期会做一个插件这个插件其实就是类似于方式二当然也可以在主程序中将插件通过方式三加载到全局方便后面直接使用。2.多模块引入1.概况为了重现方式二我们可以设定三个模块分别为模块A、模块B、模块C。其中模块A为主程序入口模块A引入模块B和模块C模块B又进入模块C。执行代码之前需要先将所有模块和配置文件保存到设备然后就能通过编辑器启动了。各文件整体架构如下2.主程序配置在项目根目录中创建“project.json”文件并且将主程序设置为A模块。需要特别注意配置文件中不要加注释内容否则无法解析。{ name: CSDN辅助, main: A.js, launchConfig: { hideLogs: false, displaySplash: true }, ignore: [ build ], packageName: com.py.csdn, versionName: 1.0.0, versionCode: 1 }3.A模块在文件系统部分已经介绍了相对路径兼容性代码在A模块中已经使用。我们可以将最终的relativeFolder变量保存到全局中在其他模块可以直接使用这个变量这样设置可以保证只需要改主程序的环境文件夹就可以做到整个脚本自动切换。我再次提醒下涉及到文件读取或者加载都得先保存代码到设备然后才能成功运行。// 生产环境相对路径文件夹 let procRelativeFolder ./; // 项目名称根据实际情况替换 let projectName 模块; // 开发环境相对路径文件夹 let devRelativeFolder files.cwd() / projectName /; // 相对路径文件夹 // 开发时切换到开发环境 // 打包时切换到生产环境 // 读取相对路径文件时都采用这种方式 // 为了实现编辑器能够直接运行切换为开发环境 let relativeFolder devRelativeFolder; // 将相对文件路径保存到全局方便其他模块使用 global.relativeFolder relativeFolder; // 引入B模块 let bObj require(relativeFolder B.js); bObj.log(A模块调用); // 引入C模块 let cObj require(relativeFolder C.js); cObj.log(A模块调用); // 删除全局自定义变量 delete global.relativeFolder;4.B模块// 获取相对路径文件夹 let relativeFolder global.relativeFolder; // 引入C模块 let cObj require(relativeFolder C.js); cObj.log(B模块调用); // 设置模块对象 let bObj {}; bObj.log function (msg) { console.log(这里是B模块打印为 msg); } // 导出模块对象 module.exports bObj;5.C模块// 设置模块对象 let cObj {}; cObj.log function (msg) { console.log(这里是C模块打印为 msg); } // 导出模块对象 module.exports cObj;6.控制台打印保存项目到设备后在A模块直接运行代码显示以下信息。如果理解了这个打印顺序和三个模块之间的关系以后可以自己灵活设置自己的模块。3.全局引入1.概况我后面会封装一个pyGlobal的插件下面会以这个插件为例介绍下如何全局引入后面再如何使用。为了减少文件在A模块已经测试“多模块引入”的基础上引入pyGlobal插件并且引入D模块。A模块调用D模块的函数在这个函数中D模块调用全局的插件函数。整体结构如下插件内容就不提供了知道调用了插件里面一个函数即可。2.A模块// 生产环境相对路径文件夹 let procRelativeFolder ./; // 项目名称根据实际情况替换 let projectName 模块; // 开发环境相对路径文件夹 let devRelativeFolder files.cwd() / projectName /; // 相对路径文件夹 // 开发时切换到开发环境 // 打包时切换到生产环境 // 读取相对路径文件时都采用这种方式 // 为了实现编辑器能够直接运行切换为开发环境 let relativeFolder devRelativeFolder; // 将相对文件路径保存到全局方便其他模块使用 global.relativeFolder relativeFolder; // 引入B模块 let bObj require(relativeFolder B.js); bObj.log(A模块调用); // 引入C模块 let cObj require(relativeFolder C.js); cObj.log(A模块调用); // 引入插件 let pyGlobal require(relativeFolder pyGlobal.js); //将插件引入全局 global.pyGlobal pyGlobal; // 引入D模块 let dObj require(relativeFolder D.js); dObj.getCurrentTime(); // 删除全局自定义变量 delete global.relativeFolder; delete global.pyGlobal;3.D模块// 从全局中获取插件 let pyGlobal global.pyGlobal; // 设置模块对象 let dObj {}; dObj.getCurrentTime function () { let currentTime pyGlobal.getCurrentTime(); console.log(这里是D模块当前时间戳为 currentTime); } // 导出模块对象 module.exports dObj;4.控制台打印