尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

pragmatic-drag-and-drop 文档示例中的 SVG 头像资源工程化:raw/processed 双目录与 CodeSandbox 兼容方案解析

pragmatic-drag-and-drop 文档示例中的 SVG 头像资源工程化:raw/processed 双目录与 CodeSandbox 兼容方案解析 pragmatic-drag-and-drop 文档示例中的 SVG 头像资源工程化raw/processed 双目录与 CodeSandbox 兼容方案解析【免费下载链接】pragmatic-drag-and-dropFast drag and drop for any experience on any tech stack项目地址: https://gitcode.com/GitHub_Trending/pr/pragmatic-drag-and-drop在 pragmatic-drag-and-drop 仓库的文档示例中packages/documentation/examples/data/people/images/目录专门存放了一组用于模拟「人员卡片」的头像资源并通过一份简短而实用的 README 解释了它的组织方式所有头像 SVG 被拆分为raw/与processed/两个目录前者保存原始 SVG 文件后者保存由 CodeSandbox 兼容性考量而生成的「SVG Data URI」编码产物。这篇文章将以该 README 为核心结合仓库内的生成脚本、数据结构与使用示例完整还原这套「原始素材 工程化产物分离」的资源管理方案为什么要分目录、编码规则是什么、生成流程如何运转、最终在示例代码中如何被消费以及这套模式对构建工具链和开发工作流的启示。一、背景为什么要为头像图片单独建立一套目录结构在讲解实现细节之前先明确这份 README 交代的核心事实图片被分离到两个独立文件夹目的是绕开 CodeSandbox 的已知问题。具体而言./raw存放用于制作的原始 SVG 文件./processed存放从.ts文件导出的、已编码为 SVG Data URI 字符串的产物项目优先使用 processed 产物而不是直接引用.svg文件因为 CodeSandbox 对.svg导入的支持不佳CodeSandbox does not handle.svgimports well。这是一个很典型的工程取舍当示例代码需要同时满足「本地开发环境」「构建发布管线」与「在线沙箱CodeSandbox」多种运行时直接依赖静态资源导入语法如import avatar from ./avatar.svg会引入构建器差异风险。把 SVG 转成纯字符串 Data URI 并放进 TypeScript 模块就可以让资源在任何环境下都以「普通 JS 字符串模块」的形式被加载从根本上规避.svg导入兼容性问题。二、目录剖析raw/ 与 processed/ 的实际内容在当前仓库中两个目录都是真实存在的且一一对应。2.1 raw/原始 SVG 素材packages/documentation/examples/data/people/images/raw/下包含 33 个 SVG 文件每个文件对应一位示例「人员」的头像例如Alexander.svgAliza.svgAlvin.svgAngie.svgArjun.svgBlair.svg……Vania.svg这些是供人工维护、二次编辑的原始矢量素材命名与人员姓名保持一致方便按名字查找对应头像。2.2 processed/编码后的 TypeScript 产物packages/documentation/examples/data/people/images/processed/下包含与 raw 目录同名的 33 个.ts文件如Alexander.ts、Vania.ts等。每个文件的核心内容是一个export default的字符串常量其值为一段经过 URL 编码的 SVG Data URI。以 processed/Alexander.ts 为例去掉头部注释后其形态是export default data:image/svgxml,%3Csvg width256 height256 ...%3E...%3C/svg%3E;可以看到MIME 类型为data:image/svgxml字符串中的、、#等特殊字符均被百分号编码如%3Csvg、%3E、%23FF5630换行被全部移除整体压缩为单行字符串。2.3 双目录为什么是必要的从仓库结构可以推断这套设计的用意raw/ 保持「人可读」原始 SVG 便于设计师与开发者查看、修改、对比processed/ 保持「机器可用」编码后的.ts模块不依赖 SVG 导入能力可以在任何支持 TypeScript 的打包器、测试运行器、CodeSandbox 中稳定工作两个目录通过生成脚本保持同步而不是手工维护避免编码产物与原始素材失配。三、生成机制codegen 脚本如何把 SVG 转成 Data URI 模块processed 产物并非手工编写而是由仓库中的 codegen.ts 自动生成的。这份脚本是整个方案的「引擎」值得逐段拆解。3.1 定位资源目录const imageFolder path.resolve(__dirname, ../examples/data/people/images); const svgFiles await glob(${imageFolder}/raw/*.svg);脚本首先解析出examples/data/people/images的绝对路径然后用fast-glob匹配raw/目录下的全部 SVG 文件。3.2 生成 Data URIconst svg await fs.readFile(file, { encoding: utf8 }); const dataURI data:image/svgxml,${svg.replace(/\n/g, ).replace(/[#]/g, encodeURIComponent)}; const source export default ${dataURI};这段代码精确对应了我们在Alexander.ts中看到的产物特征以 UTF-8 读取 SVG 源文件用replace(/\n/g, )移除所有换行把多行 SVG 压成一行对#、、三个字符调用encodeURIComponent做百分号编码——这正是为什么编码结果里出现%3C、%3E、%23拼接成data:image/svgxml,...前缀并包进export default ...的模块源码。3.3 签名与落盘const signedSource createSignedArtifact( source, yarn workspace atlaskit/pragmatic-drag-and-drop-docs codegen, This exists to workaround CodeSandbox issues with importing SVGs, ); const outputFolder path.join(imageFolder, processed); await fs.mkdir(outputFolder, { recursive: true }); await fs.writeFile( path.join(outputFolder, path.basename(file).replace(.svg, .ts)), signedSource, );这里有几个值得注意的工程细节产物文件带签名头使用createSignedArtifact生成包含codegen标记与命令来源的头部注释防止开发者误以为这是手写代码而直接修改Alexander.ts头部注释中的THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY与codegenCommand yarn workspace atlaskit/pragmatic-drag-and-drop-docs codegen即来源于此文件名通过path.basename(file).replace(.svg, .ts)转换保证raw/Alexander.svg→processed/Alexander.ts的命名一一对应输出目录用recursive: true创建首次运行不会因目录不存在而报错。3.4 重新生成的命令从产物头部注释可以还原出完整的再生成命令yarn workspace atlaskit/pragmatic-drag-and-drop-docs codegen也就是说当raw/目录中的 SVG 素材发生变化新增头像、调整配色、修改图形后只要在仓库根目录执行上述命令processed/下的.ts产物就会被整体重建保持双目录同步。这也是「raw 作为唯一事实来源、processed 作为构建产物」的标准 codegen 工作流。四、消费方式processed 产物如何进入示例数据层生成好的头像模块最终通过 data/people/index.tsx 被组织成示例可用的数据模型。4.1 显式静态导入import Alexander from ./images/processed/Alexander; import Aliza from ./images/processed/Aliza; // …… 共 33 个头像逐一显式导入index.tsx顶部注释特别说明这些导入必须显式写出来因为它们需要能被静态分析statically analyzable才能被正确地上传到 CodeSandbox。这正是整个方案的闭环既然不依赖.svg导入那么所有的资源引用都必须是可静态识别的普通模块导入这样才能被沙箱环境完整搬运。4.2 构建头像映射表与 Person 数据模型export type Person { userId: string; name: string; role: string; avatarUrl: string; }; const avatarMap: Recordstring, string { Alexander, Aliza, // …… Vania, };33 个导入的头像被收进avatarMap以姓名为键、Data URI 字符串为值。Person.avatarUrl直接使用这个字符串说明Data URI 可以无缝充当img的src这也是把 SVG 转成 data URI 的核心收益之一——不需要网络请求即取即用。4.3 确定性取人逻辑let sharedLookupIndex: number 0; export function getPerson(): Person { sharedLookupIndex; return getPersonFromPosition({ position: sharedLookupIndex }); }getPerson通过递增计数器取人并刻意不使用随机数注释中明确说明这是为了「对 VR 测试保持稳定」this does not use randomness so that it is stable for VR tests。这一点与整个示例体系的测试策略一脉相承示例数据必须是确定性的视觉回归测试Visual Regression才能得到可对比的快照。五、实际使用链路从数据模块到看板示例这套头像资源最终服务于文档目录下的多个看板类示例例如board.vr.ap.tsx基础看板示例导入getBasicData与Person类型board-with-multi-drag.tsx多元素拖拽示例board-with-overflow-scroll.tsx溢出滚动看板示例。它们共同的使用模式是import { type ColumnMap, type ColumnType, getBasicData, type Person } from ./data/people;getBasicData()会生成包含 Confluence、Jira、Trello 三个看板列、每列 10 个人的演示数据其中每个人的avatarUrl都来自 processed 目录中的 Data URI 模块。这样一来本地开发时资源以字符串模块形式被 Vite/Webpack 等工具正常处理部署文档站点时无需额外的 SVG 资源路径配置上传到 CodeSandbox 时不依赖其对 SVG 导入的兼容性行为与本地完全一致。六、方案总结与适用边界回顾这份 README 及其周边实现可以提炼出几个可复用的工程要点素材与产物分离raw/保存人工维护的原始资源processed/保存自动生成的消费产物两者通过 codegen 脚本保持同步避免「改了一处忘了另一处」以 CodeSandbox 兼容性为硬约束当目标运行环境对静态资源导入支持不完整时把资源编码为 Data URI 字符串模块是一种轻量、零依赖的规避手段且能通过静态导入被沙箱完整迁移codegen 产物必须带签名通过createSignedArtifact生成「DO NOT MODIFY」头部防止产物被当作手写代码手工修改保证下次生成时可以被安全覆盖确定性数据服务测试示例数据层刻意避免随机性确保 VR 快照测试可复现。同时也要明确其适用前提与限制该方案针对的是示例/文档型代码库中的少量固定资源33 个矢量头像且资源以字符串内联进 bundle对于生产环境中的大量图片、需要 HTTP 缓存与 CDN 分发的大体积资源直接内联为 Data URI 通常不是最优选择。此外编码产物依赖raw/目录作为事实来源任何对processed/的手工修改都会在下次运行yarn workspace atlaskit/pragmatic-drag-and-drop-docs codegen时被覆盖——这既是保护机制也意味着「永远只改 raw不改 processed」。如果需要在当前仓库中验证这套机制可以依次查看 README设计意图、codegen.ts生成逻辑、Alexander.ts产物样例与 index.tsx消费入口即可完整串起「原始 SVG → 编码 Data URI 模块 → 头像映射表 → 看板示例」的整条链路。【免费下载链接】pragmatic-drag-and-dropFast drag and drop for any experience on any tech stack项目地址: https://gitcode.com/GitHub_Trending/pr/pragmatic-drag-and-drop创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表