ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

WebToApp 扩展模块(Extension Modules)配置实战:在「编辑通用配置」中为 APK 应用挂载 JS/CSS 扩展、用户脚本与 MV3 浏览器扩展

WebToApp 扩展模块(Extension Modules)配置实战:在「编辑通用配置」中为 APK 应用挂载 JS/CSS 扩展、用户脚本与 MV3 浏览器扩展 WebToApp 扩展模块Extension Modules配置实战在「编辑通用配置」中为 APK 应用挂载 JS/CSS 扩展、用户脚本与 MV3 浏览器扩展【免费下载链接】web-to-appThe most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone项目地址: https://gitcode.com/GitHub_Trending/web/web-to-app导读本篇技术指南聚焦 WebToApp 中Extension Modules扩展模块这一能力卡片它位于每个应用的「编辑通用配置Edit Common Config」编辑器内负责把项目内已安装的扩展JS/CSS 模块、用户脚本、MV3 Chrome 扩展按应用粒度挂载到生成的 APK 中。读完本文你将掌握extensionEnabled、extensionModuleIds、extensionFabIcon三个配置项的完整语义理解扩展从「模块库管理 → 应用配置 → WebView 生命周期注入」的完整链路并能读懂仓库内置模块的module.json清单动手配置出属于自己应用的扩展组合。一、功能定位给“已发布的应用”留的后门WebToApp 的扩展体系在设计上有一个鲜明特点应用打包发布之后依然可扩展。扩展不写死在应用逻辑里而是由统一的ExtensionManager管理、由 WebView 在页面生命周期钩子处注入因此同一套扩展体系同时服务于“打包前的配置”与“打包后的运行”两个阶段。本文要讲解的正是打包前配置这一环——在「编辑通用配置」的Extension modules卡片里完成三个关键设置。在编辑器中的入口位置见 编辑通用配置总览在应用卡片上点击⋮→Edit Common ConfigWeb 类应用直接显示为Edit在「Extensions network」分区即可找到Extension Modules卡片。二、卡片上的三个配置项该卡片提供三个核心选项分别对应数据模型WebApp中的三个字段见 WebApp.kt卡片选项对应字段类型与默认值作用EnableextensionEnabledBoolean false总开关仅为当前应用启用/停用整套扩展注入Selected modulesextensionModuleIdsListString emptyList()选择哪些已安装模块运行在该应用中按模块id精确匹配FAB iconextensionFabIconString? null扩展面板悬浮按钮Floating Button的图标空值使用默认图标这三个字段在打包时会被写入 APK 的运行时配置。在 ApkConfigJsonFactory.kt 中可以看到它们被序列化为 JSON 配置项extensionEnabled to extension.enabled, extensionFabIcon to extension.fabIcon, extensionModuleIds to extension.moduleIds,对应的运行时配置块定义在 ApkConfig.ktdata class ExtensionBlock( val enabled: Boolean false, val moduleIds: ListString emptyList(), val embeddedModules: ListEmbeddedExtensionModule emptyList(), val fabIcon: String )值得注意的是embeddedModules字段与“按 id 引用已安装模块”不同它是随 APK 内嵌的模块完整快照用于保证引用模块的配置在目标设备上一定可用。三、被选中模块的运行时行为仅仅在卡片上勾选模块还不够理解“勾选之后发生了什么”才能正确排错。运行时有两套匹配逻辑叠加应用级过滤只有extensionModuleIds里列出的模块且处于 enabled 状态才会进入候选集页面级过滤模块自身的urlMatches规则决定它在哪些 URL 上真正执行。ExtensionManager.generateInjectionCode()见 ExtensionManager.kt同时按runAt注入时机与sourceType排除用户脚本/Chrome 扩展它们走独立的注入通道过滤后才把模块代码包裹进带try/catch的 IIFE 注入页面val matchingModules getModulesForUrl(url).filter { it.runAt runAt it.sourceType ! ModuleSourceType.CHROME_EXTENSION it.sourceType ! ModuleSourceType.USERSCRIPT it.sourceType ! ModuleSourceType.GREASYFORK }也就是说即便模块在卡片中被选中它仍必须满足“URL 匹配”且“运行时机正确”才会生效——这解释了为什么某些模块在特定页面不工作。运行时机Run time模块数据模型ExtensionModule的runAt字段ExtensionModule.kt定义了五种注入时机ModuleRunTime触发的 WebView 生命周期事件DOCUMENT_STARTonPageStarted文档尚未开始解析DOCUMENT_ENDonPageFinished/DOMContentLoadedDOCUMENT_IDLE页面加载完成之后load事件CONTEXT_MENU长按弹出上下文菜单时BEFORE_UNLOAD页面卸载之前beforeunload从源码看该字段在ExtensionModule数据类中的默认值为DOCUMENT_END见 ExtensionModule.kt这也是 JS Modules 文档 中标注的默认值。URL 匹配规则urlMatches每个模块还携带一组 URL 匹配规则Chrome 风格 glob 或正则见matchesUrl()实现ExtensionModule.ktisRegex: false默认——Chrome 风格 glob*匹配任意内容*://展开为(https?|ftp|file)://*或all_urls匹配一切 URL其余正则元字符会被转义。glob 匹配失败时降级为大小写不敏感的contains子串匹配isRegex: true——Java 正则带200ms 超时ExtensionModule.kt超时视为“不匹配”防止恶意或低效正则在每次页面加载时卡死 UI 线程编译后的正则还经过一个容量 64 的有界 LRU 缓存exclude: true——命中即从结果集中剔除排除规则优先于包含规则。匹配语义若同时存在 include 与 exclude 规则先排除后包含若只有 exclude 规则且未命中则默认放行。四、可以挂载哪几类扩展「Selected modules」的可选范围来自Extension Modules 管理页入口主界面⋮→ Extension Modules见 管理文档。四类来源会被归一化进同一个内部模型ExtensionModule见 扩展作者指南类型形态典型用途JS Modulemodule.json清单 main.js可选 CSS带配置 UI 和悬浮面板的自定义功能能力最强CSS Module纯样式覆盖仍需一个main.js桩文件主题、重排版、深色模式UserscriptTampermonkey/Greasemonkey 风格.user.js移植现有用户脚本暴露GM_*APIChrome MV3Manifest V3 Chrome 扩展移植浏览器扩展暴露chrome.*API归一化的关键证据在数据类ExtensionModuleExtensionModule.kt它同时包含sourceTypeCUSTOM / USERSCRIPT / CHROME_EXTENSION / GREASYFORK、manifestJson、gmGrants、backgroundScript、popupPath、worldISOLATED/MAIN等字段说明四类扩展共用同一套配置、分享与注入通道。管理页提供的核心能力对应 管理文档List toggle——按应用开关已安装扩展对应extensionModuleIds的选择操作Editor——创建/编辑模块清单、JS、CSS、配置项与交互面板语法见 JS ModulesMarket——浏览社区模块市场发布方式见 Publish to the MarketBrowser extensions——在线搜索 Chrome Web Store 并安装 MV3 扩展见 Chrome MV3AI developer——跳转到 Agent 用 AI 生成扩展。五、模块清单module.json深度解读勾选模块前读懂它的清单有助于判断该模块是否适合你的应用。以仓库内置模块为例reading-mode 模块清单 完整展示了常见字段{ id: wta-reading-mode, name: Reading Mode, icon: menu_book, category: READING, runAt: DOCUMENT_END, urlMatches: [ { pattern: *, isRegex: false, exclude: false } ], permissions: [DOM_ACCESS, CSS_INJECT, STORAGE], configItems: [ { key: theme, name: Theme, type: SELECT, defaultValue: light, options: [light, sepia, dark] }, { key: fontSize, name: Font size (px), type: NUMBER, defaultValue: 18 } ] }关键字段在 ExtensionModule.kt 中有严格的数据类型约束category——23 个枚举值之一CONTENT_FILTER、CONTENT_ENHANCE、STYLE_MODIFIER、THEME、FUNCTION_ENHANCE、AUTOMATION、NAVIGATION、DATA_EXTRACT、DATA_SAVE、INTERACTION、ACCESSIBILITY、MEDIA、VIDEO、IMAGE、AUDIO、SECURITY、ANTI_TRACKING、SOCIAL、SHOPPING、READING、TRANSLATE、DEVELOPER、OTHER每个类别带 Material 图标与多语言名称/描述ExtensionModule.ktpermissions——31 种权限枚举如DOM_ACCESS、CSS_INJECT、STORAGE、COOKIE、LOCATION、EVAL等其中dangerous true的权限如COOKIE、NETWORK、CAMERA、MICROPHONE、LOCATION、EVAL、IFRAME在审核时会额外审查。注意权限目前是展示性的运行时并不据此做沙箱隔离configItems——22 种配置控件类型TEXT、TEXTAREA、NUMBER、BOOLEAN、SELECT、MULTI_SELECT、RADIO、CHECKBOX、COLOR、URL、EMAIL、PASSWORD、REGEX、CSS_SELECTOR、JAVASCRIPT、JSON、RANGE、DATE、TIME、DATETIME、FILE、IMAGE最终以configValues: MapString, String的形式在运行时通过getConfig(key, defaultValue)暴露给脚本ExtensionModule.kt。另一个简洁示例是 hello-world 模块清单它演示了最小可行的模块结构——greetingTEXT与durationMsNUMBER两个配置项、DOCUMENT_END运行时机、*全量 URL 匹配。main.js的编写契约详见 JS Modules代码被包裹在带try/catch的 IIFE 中报错进console.error且不破坏页面可直接访问__MODULE_INFO__、__MODULE_CONFIG__、__MODULE_UI_CONFIG__、__MODULE_PANEL_HTML__、getConfig(key, defaultValue)等全局因为外层是 IIFE顶层不能出现return语句。六、FAB 图标与悬浮面板extensionFabIcon控制扩展面板悬浮按钮的图标。当模块带有panelHtml或调用window.__WTA_MODULE_UI__.register({...})注册时ExtensionModule.kt 的自动注册逻辑WebView 内会显示一个悬浮按钮点击展开该模块的交互面板。uiConfigExtensionModule.kt支持配置项默认值说明typeFLOATING_BUTTONUI 形态目前仅悬浮按钮autoHidefalse是否自动隐藏autoHideDelay3000毫秒自动隐藏延迟initiallyHiddenfalse初始是否隐藏showOnlyOnMatchtrue是否仅在 URL 匹配时显示面板 HTML 内通过data-wta-action属性绑定window.__wta_module_action_name处理器并可使用var(--wta-*)主题变量匹配应用主题见 JS Modules。七、扩展的分享、导入与持久化配置卡片面向“已安装模块”的选择而模块本身的流转依赖以下机制见 ExtensionManager.kt存储布局用户模块保存在应用私有目录extension_modules/modules.json代码与 CSS 以侧车文件形式分离存储code_id.js、css_id.css、codefiles_id/modules.json只保留元数据内置模块的启用状态单独存于builtin_states.json。若modules.json解析失败管理器会自动把损坏文件备份为modules_backup_时间戳.json后再恢复ExtensionManager.kt文件交换单个模块导出为.wtamod多模块打包为.wtapkg导入时会重新生成id并强制builtIn false二维码分享码WTA1:完整 gzip Base64与WTA2:仅携带与默认值的差异字段 最高压缩兼容旧版解码器单二维码物理上限为 2953 字节ExtensionModule.kt超过上限自动切换为 V2 编码。八、使用中的三个重要注意点扩展作者指南 明确指出了与浏览器扩展平台的三个行为差异配置与排错时务必记住用户脚本的GM_*函数不受grant门控——全部无条件暴露Chrome 的ISOLATED/MAIN世界并非真正隔离——Android WebView 只有一个 JS 上下文隔离是模拟的GM_notification仅记录日志MV3 的“后台 service worker”实际是一个隐藏 WebView而非真正的 service worker。九、完整的配置工作流结合以上全部机制推荐的最小可用流程如下在Extension Modules 管理页主界面⋮→ Extension Modules安装或创建所需模块内置模块无需安装打开目标应用的Edit Common Config→Extension modules卡片打开Enable开关写入extensionEnabled true在Selected modules中勾选需要的模块写入extensionModuleIds按需修改FAB icon写入extensionFabIcon保存后重新导出/打包 APK运行时WebViewManager会按各模块的runAt与urlMatches在对应页面注入代码。若某个模块在页面中不生效优先检查该模块是否在卡片中被勾选、是否enabled、其urlMatches是否覆盖当前页面、runAt是否与预期时机一致以及是否属于需要走独立注入通道的用户脚本/Chrome 扩展类型。十、延伸阅读编辑器全量能力卡列表编辑通用配置总览扩展模块管理页Extension Modules管理四类扩展总览与注入模型Extension AuthoringJS 模块清单与main.js契约JS Modules用户脚本GM_*API 参考Userscripts源码级实现ExtensionModule.kt数据模型/URL 匹配/分享码、ExtensionManager.kt管理/注入、ApkConfig.kt打包配置块可参考的完整示例清单modules 目录、模块注册表【免费下载链接】web-to-appThe most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone项目地址: https://gitcode.com/GitHub_Trending/web/web-to-app创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表