1142 words
6 minutes
解决iOS文档绝对路径问题的CLI工具
2025-03-11 09:28:26
2025-03-11 15:53:19

解决iOS文档绝对路径问题#

为了解决iOS生成document绝对路径不匹配线上服务器路径的问题,我为iOS团队开发了一个脚手架工具解决了这个问题。

项目目标#

  • 解决DocC文档绝对路径问题
  • 开发简单易用的CLI工具
  • 支持批量处理多个文档
  • 添加自动化测试

素材准备#

项目地址:SlothCreatorBuildingDocCDocumentationInXcode

步骤1

如图所示,随后生成了SlothCreator.doccarchive这个包,这个就是我的目标。

问题分析#

预期表现(点击展开)
Debug cd SlothCreator.doccarchive SlothCreator.doccarchive pnpx http-server Starting up http-server, serving ./ http-server version: 14.1.1 http-server settings: CORS: disabled Cache: 3600 seconds Connection Timeout: 120 seconds Directory Listings: visible AutoIndex: visible Serve GZIP Files: false Serve Brotli Files: false Default File Extension: none Available on: http://127.0.0.1:8080 http://192.168.6.207:8080 Hit CTRL-C to stop the server

然后访问http://127.0.0.1:8080/documentation/slothcreator,展示的效果同Xcode,符合预期:

初期成功对比图

项目根路径改变后#

当我们改变项目根路径后:

^Chttp-server stopped. SlothCreator.doccarchive cd ../ && pnpx http-server Starting up http-server, serving ./ http-server version: 14.1.1 http-server settings: CORS: disabled Cache: 3600 seconds Connection Timeout: 120 seconds Directory Listings: visible AutoIndex: visible Serve GZIP Files: false Serve Brotli Files: false Default File Extension: none Available on: http://127.0.0.1:8080 http://192.168.6.207:8080 Hit CTRL-C to stop the server

页面打开失败:

页面打开失败

控制台错误信息:

GET http://127.0.0.1:8080/js/chunk-vendors.bdb7cbba.js net::ERR_ABORTED 404 (Not Found) GET http://127.0.0.1:8080/css/index.3a335429.css net::ERR_ABORTED 404 (Not Found) GET http://127.0.0.1:8080/js/index.0d775bb6.js net::ERR_ABORTED 404 (Not Found)

根本原因#

既然找不到资源,那么直接打开文件夹去查找静态资源,一查直接定位根本原因:绝对路径

绝对路径问题

解决方案:在当前环境下,只需将/js/[index.0d775bb6.js]这类模式的静态资源全部替换成 /SlothCreator.doccarchive/js/[index.0d775bb6.js]即可。

尝试手动修复#

直接通过IDE的replace All功能修复一版本, 发现问题依旧存在。部分资源是js动态注入的. 动态资源路径问题

灵光一闪,先试试看xcode自带的工具转换的是啥格式的,然后我的js逻辑再照抄不就行了吗(官方工具之所以没有在内部项目使用,是因为在复杂项目中有bug, 并且issue仍然未被修复)

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/docc process-archive transform-for-static-hosting SlothCreator.doccarchive \ --hosting-base-path /SlothCreator.doccarchive

替换完成后,通过IDE搜索SlothCreator.doccarchive

对比

这里能分析出两个问题

  1. 处理对象有且仅有html文件.
  2. 处理pattern除了js和css, 还有baseUrl = "/"这种pattern. 默认导出

CLI 工具开发方案#

使用的技术栈#

工具用途版本
cac命令行参数解析^6.7.14
fs-extra增强的文件系统操作^11.3.0
tsupTypeScript打包工具^8.4.0
typescript开发语言^5.8.2

实现步骤#

  1. 初始化项目

    mkdir path-fixer && cd path-fixer npm init -y npm i cac fs-extra npm i -D typescript tsup @types/fs-extra
  2. 创建主要功能模块 项目结构分为三个主要文件:

    • index.ts: 命令行入口和主流程
    • replacer.ts: 路径替换核心逻辑
    • logger.ts: 日志处理功能
  3. 发布到npm

    # 构建项目 npm run build # 发布到npm npm publish --access=public

使用示例#

# 安装 npm install -g @0bipinnata0/path-fixer # 使用 path-fixer fix ./SlothCreator.doccarchive --base-url=/SlothCreator.doccarchive # 显示详细日志 path-fixer fix ./SlothCreator.doccarchive --base-url=/SlothCreator.doccarchive --verbose

或者

pnpx @0bipinnata0/path-fixer fix ./SlothCreator.doccarchive --base-url=/SlothCreator.doccarchive

修复后的效果#

默认导出


补充说明#

NOTE

此工具仅适用于DocC生成的文档,其他类型的文档可能需要不同的处理方式。

TIP

如果你遇到类似问题,可以考虑使用此工具或参考其实现原理。

WARNING

在生产环境中使用前,请务必进行充分测试!

代码实现核心部分#

// 核心替换逻辑 export function replaceAbsolutePaths(filePath: string, baseUrl: string, logger: ILogger = defaultLogger): string | null { try { const content = fs.readFileSync(filePath, 'utf8'); // 标准化 baseUrl,确保前后都有且仅有一个斜杠 const normalizedBaseUrl = normalizeUrl(baseUrl); // 如果 baseUrl 是根路径 "/",则不需要替换 if (normalizedBaseUrl === '/') { return null; } // 创建一个新的内容副本用于修改 let newContent = content; // 替换 baseUrl = "/" 为用户指定的 baseUrl newContent = newContent.replaceAll(`baseUrl = "/"`, `baseUrl = "${normalizedBaseUrl}/"`); // 替换 href="/css 为 href="/baseUrl/css newContent = newContent.replaceAll(`href="/css`, `href="${normalizedBaseUrl}/css`); // 替换 src="/js 为 src="/baseUrl/js newContent = newContent.replaceAll(`src="/js`, `src="${normalizedBaseUrl}/js`); // 如果内容有变化,返回新内容 if (content !== newContent) { return newContent; } return null; } catch (error) { logger.error(`处理文件 ${filePath} 时出错:`, error); return null; } } /** * 确保 URL 前后都有且仅有一个斜杠 */ function normalizeUrl(url: string): string { if (!url) return '/'; // 移除开头的所有斜杠 let normalized = url.replace(/^\/+/, ''); // 移除结尾的所有斜杠 normalized = normalized.replace(/\/+$/, ''); // 如果处理后为空,返回单个斜杠 if (!normalized) return '/'; // 添加开头的斜杠 return '/' + normalized; }

源码地址#

完整源码可以在这里找到:path-fixer

解决iOS文档绝对路径问题的CLI工具
https://0bipinnata0.my/posts/cli/replace_absolute_path/
Author
0bipinnata0
Published at
2025-03-11 09:28:26