ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

authentik 前端维护指南:解读 web/tools 一次性重构脚本库与 HTMLElementTagNameMap 补全实践

authentik 前端维护指南:解读 web/tools 一次性重构脚本库与 HTMLElementTagNameMap 补全实践 authentik 前端维护指南解读 web/tools 一次性重构脚本库与 HTMLElementTagNameMap 补全实践【免费下载链接】authentikThe authentication glue you need.项目地址: https://gitcode.com/GitHub_Trending/au/authentik在 authentik 这样一个体量庞大的开源项目中前端web/src目录下散布着上千个 TypeScript 文件、数百个 Lit Web Component如何安全、批量地完成跨全系统的语法级改造是每个维护者都会遇到的现实问题。本文以仓库内 web/tools/README.md 为骨架结合其中唯一的实际工具脚本与相关源码系统讲解 authentik 如何用一次性重构脚本解决这类问题——包括脚本的设计思路、具体实现、失败条件以及 HTMLElementTagNameMap 全局类型声明在 Lit 组件体系中的价值。读完本文你将掌握一种可复用的代码库级重构方法论也能直接看懂并复用仓库中这份现成的 codemod 脚本。一、web/tools 是什么一次重构的杂物抽屉web/tools/README.md 用一句非常直白的话定义了整个目录的定位Thetoolsfolder is a junk drawer——这是一个存放所有小型重构工具的杂物抽屉。这段话揭示出 authentik 前端维护中的三个关键事实全系统级语法修改发生得极为频繁web/src目录下包含 1042 个文件其中 926 个为.ts一个跨文件的语法变更往往涉及几十甚至上百个文件逐一手改既不现实也容易遗漏修改方法本身需要被记录README 明确指出保留这些工具的目的之一是keep and documenthowthose changes were made即重构的做法和产物同样重要工具是可复用的框架而非一次性废品README 强调把工具集中存放意味着future syntactical changes wont have to start from scratch未来的语法改动不必从零开始总能在tools里找到可复制、可借鉴的框架。因此web/tools的实际角色是一个内部 codemod 脚本库它保存的是一次性脚本但沉淀的是一种可持续的重构能力。二、目录现状一份规范、一个真实工具当前 web/tools 目录下只有两个文件文件说明README.md目录用途说明与维护规范20240625-add-htmlelementtagnamemaps-to-everything.py为缺失声明补全 HTMLElementTagNameMap 的 Python 脚本注意脚本的文件名遵循了 README 提出的唯一硬性规范——If you add a tool to this repo, pleasedateit以日期20240625即 2024 年 6 月 25 日作为前缀加上描述性的动作与目标add-htmlelementtagnamemaps-to-everything。这样做的好处一目了然任何人在任何时候翻看这个目录都能立刻知道该工具是何时使用、针对什么问题并判断它是否仍与当前的开发流程相关README 原文so we can track when it was used, and if its still relevant to the development process。三、背景知识Lit Web Component 与 HTMLElementTagNameMap要理解这个工具解决什么问题先要理解 authentik 前端的组件体系。authentik 前端基于 Lit 构建所有业务组件最终都继承自 web/src/elements/Base.ts 中的AKElement而AKElement本身继承自LitElement。组件通过 Lit 的customElement装饰器注册为浏览器原生自定义元素例如 web/src/admin/admin-overview/AdminOverviewPage.ts 中的写法customElement(ak-admin-overview) export class AdminOverviewPage extends AdminOverviewBase { // ... }这里的ak-admin-overview就是注册到浏览器的自定义标签名。这类标签名在 authentik 中统一使用ak-前缀与项目代号一致。问题出在 TypeScript 的类型系统上。当你在模板或 JavaScript 中通过document.createElement(ak-admin-overview)创建元素时TypeScript 默认返回的是泛泛的HTMLElement类型你无法直接访问AdminOverviewPage类上定义的属性和方法。浏览器与 TS 生态给出的标准解法是通过**全局接口增强global augmentation**扩展HTMLElementTagNameMapdeclare global { interface HTMLElementTagNameMap { ak-admin-overview: AdminOverviewPage; } }一旦声明了这条映射document.createElement(ak-admin-overview)的返回值就会被推断为AdminOverviewPageIDE 自动补全、类型检查与重构跳转全部随之生效。这正是该工具要批量注入的内容——在 AdminOverviewPage.ts 的文件末尾可以看到实际生成的declare global块。四、核心工具深度解析20240625-add-htmlelementtagnamemaps-to-everything.py这个 Python 脚本是极简语法导向a very primitive syntactically-oriented script的一次性工具它不做 AST 解析纯粹靠正则匹配完成注入。整个逻辑值得逐段拆解。4.1 三个核心正则脚本开头定义了三个编译好的正则分别对应一次注入所需的全部信息customElement_re re.compile(rcustomElement\(([^])) # 捕获自定义元素标签名 class_re re.compile(rclass\s(\w)\sextends) # 捕获类名 tagmap_re re.compile(rinterface HTMLElementTagNameMap) # 检测是否已存在声明customElement_re从customElement(ak-xxx)中提取标签名class_re从class Xxx extends ...中提取类名tagmap_re用于判断目标文件是否已经包含HTMLElementTagNameMap接口避免重复注入。4.2 五重失败条件检查安全第一脚本名为to everything但实际执行时极其保守。inject()函数在写入前会依次检查五个失败条件任何一条不满足就直接跳过该文件并打印原因检查条件跳过原因customElement声明多于 1 个组件声明过多无法确定注入哪一个class声明多于 1 个类声明过多无法确定注入哪一个已存在HTMLElementTagNameMap目标已存在跳过避免重复找不到customElement非自定义组件文件找不到class结构异常无法定位类名除此之外还有一个非常关键的位置约束customElement声明的下一行必须紧跟着class声明searchCustomElement[0][0] 1 ! searchClass[0][0]时跳过。这是因为脚本假设装饰器与类定义相邻customElement(ak-xxx)的下一行就是class Xxx extends ...README 也明确承认如果extends子句与class关键字不在同一行脚本同样找不到。这些限制正是primitive一词的注脚也是该工具被定位为一次性脚本而非通用工具的原因。4.3 注入逻辑与产物通过全部检查后脚本把文件名与类名填入模板追加到文件末尾text.extend([ \n, declare global {\n, interface HTMLElementTagNameMap {\n, {}: {};\n.format(ceName, clName), }\n, }\n, \n ])生成的效果与 AdminOverviewPage.ts 中手写/注入的块完全一致declare global { interface HTMLElementTagNameMap { ak-admin-overview: AdminOverviewPage; } }4.4 使用方式脚本文件头部注释给出了实际的调用方式配合 ripgrep 找出所有使用了customElement的文件逐个喂给脚本for i in $(rg -l customElement src/); do python add-global $i ; done由于inject()对每个失败条件都会print原因批量执行后可以通过输出快速审计哪些文件被跳过、为什么被跳过跳过的少数文件再由人工补齐。五、实战数据与效果360 个组件95% 一次修复脚本头部注释记录了这次重构的真实数据可以作为评估其效果的可靠依据there were 360 web components in our system that lacked entries into the HTMLElementTagNameMap global space and about 95% of them were fixed with this pass; the rest were done by hand.也就是说本次重构共发现360 个 Web Component 缺少HTMLElementTagNameMap条目其中约95% 由这一轮脚本自动修复剩余 5%约十几二十个因触发上述失败条件而被跳过由人工接手处理。从当前仓库源码可以印证这次改造的成果在 web/src 下抽查admin/admin-overview、admin/admin-settings等目录绝大多数组件文件末尾都已带上了declare global { interface HTMLElementTagNameMap { ... } }块。可以说正是这次95% 自动化 5% 人工兜底的组合拳让 authentik 前端的自定义元素类型系统在极短时间内完成了整体补全。六、方法论沉淀从一次性脚本到长期资产透过这个目录和这份脚本authentik 的维护实践至少给出三点可迁移的经验为一次性的系统级修改留下可复现的工具。语法级重构通常只执行一次但怎么改的值得存档。web/tools用最轻量的方式一个目录 一个 README 一个脚本保存了完整的做法未来同类改动不必重新设计。工具的失败条件本身就是最好的文档。这个脚本的五重检查不仅保证了安全性还以输出日志的形式暴露了所有无法自动化的边缘情况让人工兜底有据可依——这正是 README 强调的keep and documenthowthose changes were made。用日期 动作描述命名工具。20240625-add-htmlelementtagnamemaps-to-everything.py这一命名让脚本的生命周期一目了然也方便后续判断其是否已过时。对任何维护大型前端代码库的团队而言这套杂物抽屉哲学都值得借鉴不必追求完美的通用工具把每一次脏活累活的执行方式诚实记录下来就是下一场重构最好的起点。【免费下载链接】authentikThe authentication glue you need.项目地址: https://gitcode.com/GitHub_Trending/au/authentik创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表