前端物料库的设计

1. 背景

在开发新项目或需求的过程中,前端开发通常需要经历一个物料收集阶段。这一阶段的核心目标是寻找是否已存在可复用的组件,这些组件可能以 npm 包、UMD 组件或 SVG 图标的形式存在。然而,在收集这些物料时,我们常面临以下挑战:

  1. 如何判断公司内部是否有推荐的公共基础库来实现特定功能(例如唤端)?
  2. 当了解到某个组件可能满足当前需求时,如何快速找到该组件的使用文档 ?

此前,前端开发人员多通过咨询同事或查阅过往相似功能代码来确定所需组件,这种方式效率较低。对于组件相关文档,若为 npm 包,虽可通过公司内部搭建的 cnpm 系统搜索查阅 readme 文档,但 UMD 组件的文档却分散于各个 info 文档中,检索极为不便。

随着 npm 包数量的持续增长以及公司前端业务的不断拓展,内部 cnpm 系统逐渐暴露出一系列问题:

  1. 该系统搭建已久,所采用的开源版本陈旧,缺失产物预览等实用功能;

  2. 其功能较为单一,仅能对 npm 包进行管理,无法涵盖 UMD 组件和 SVG 图标等前端物料;

  3. cnpm 的搜索能力欠佳,无法依据特定条件进行筛选,对中文搜索的支持也不尽人意。

与之配套的 npm publish 功能,也同样面临着下面的问题:

  1. 作为发布 npm 包的工具,npm publish 只能发布 npm 物料;

  2. npm 有单独的账号体系,与公司的域账号体系不兼容;

  3. npm publish 的发布流程缺少公司流程规范的支持,比如发布描述;

  4. npm publish 无法记录本次版本与仓库 commit hash 的关系,后续难以追踪到相关代码。

因此,我们打造一个全新的前端物料平台,来解决上述的问题。

2. 方案

Nexus3 是一个开源的仓库管理工具,支持多种包格式如 Maven、npm、NuGet 等,用于存储、组织和分发软件构件。它能代理公共仓库(例如Maven Central、npmjs.org),缓存第三方依赖以加速下载并减少构建失败风险。同时,nexus3 支持搭建私有仓库,增强项目安全性和独立性,允许团队成员共享内部构件,避免发布到公共仓库。

公司内部基架团队已完成 nexus3 系统的搭建,并且推动公司内部以此作为统一的仓库管理平台。Nexus3 可以完美的解决 npm 的发布、下载、代理等功能,但同样有以下的问题:

  1. 没有门户页面,用户无法直接使用该系统;

  2. 搜索能力薄弱,不支持多维度搜索(比如文档、维护人、分类);

  3. 不支持文档存储与获取,用户编写的 readme 文档无法展示。

因此决定基于 nexus3 系统,做上层的封装,来支持多种物料、多种文档、多种发布方式。整体设计:

  1. Nexus3 系统提供包的存储和下载,物料库上层封装发布、废弃、retag、scope、maintainer 管理等 npm 基础功能;

  2. 在此基础增加分类、关注、预览、文档、搜索、项目依赖功能,丰富和完善物料系统;

  3. 复用 npm 的能力,支持 UMD 物料;和图标服务打通,支持图标物料;

  4. 提供新的 cli 工具 bpm,代替原有的 npm publish,实现统一鉴权、发布描述、commit hash 记录和 UMD 物料发布;

  5. 打通前端 CI/CD 平台,实现在平台发布 npm 和 UMD 物料。

3. NPM

物料库建设的首要目的是代替原有的 cnpm 系统,并在此基础上对 npm 功能进行优化与拓展。Nexus3 仅承担 npm 包的存储和下载工作,cnpm 原有的其他功能需由物料库实现,因此需要解决以下问题:

  1. 现有的包管理工具无法满足新的需求(账号权限统一、发布描述);

  2. Nexus3 提供的数据和能力,不足以支撑 npm 门户页面的基础功能(文档、搜索、版本管理);

  3. 物料库建设完成后,cnpm 平台的数据迁移。

3.1 Bpm

在物料库的包管理工具选择上,存在两种方案:

  1. 使物料库提供的 API 适配 npm 的 API 标准,这样用户在切换到物料库源后,仍可继续使用开源包管理工具(如 npm、yarn、pnpm);
  2. 开发全新的包管理工具,以满足物料库的个性化需求。

第一种方案中,开源包管理工具的发包流程固定,难以适应公司的发布标准,也无法添加账号权限统一管理、发布记录仓库和 commit hash 等个性化功能;

第二种方案虽然能完全贴合物料库需求,但开发成本高昂,用户迁移难度大,且无法利用优秀的开源包管理工具进行项目管理和下载。

综合考量,鉴于物料库的个性化需求主要集中在发布环节,因此决定打造全新的发布管理工具 bpm。该工具仅对发布功能进行创新设计,项目管理和下载仍由开源工具提供,这样既能满足公司特定需求,又便于用户使用。

3.1.1. 权限统一

此前,公司内部基于开源 cnpm 搭建的 npm 源发布管理系统,版本较为老旧,其权限管理采用独立账号体系,与公司域账号鉴权体系相互分离。用户需要单独记忆一套账号密码,且使用 npm login 登录后,session 长期有效,长时间无需再次登录。当在更换电脑或重装系统后再次登录时,很容易遗忘密码,需要联系 cnpm 进行重置,这给用户带来诸多不便。为解决这一问题,新的物料库系统将权限管理与域账号鉴权体系进行打通,有效减轻用户的记忆负担。其整体流程如下:

3.1.2. 平台账号

域账号鉴权的集成解决了个人用户的权限问题,但由于凭证存在有效期,一段时间后需要重新登录。对于个人本地发包而言,这一问题影响较小,但公司内部部分包通过平台发布,使用公共账号进行维护。以往的做法是在本地通过 npm 登录获取鉴权 token 后,将其存储于平台用于发布。若物料库仅支持域账号鉴权,将无法满足平台发布的需求。

为此,物料库设计了独立于域账号鉴权的平台账号权限体系。具体流程:

  1. 用户向物料库提交账号名称、负责人、描述等信息,物料库签发生成随机 token 并记录到数据库,同时将 token 提供给用户;

  2. 在使用 bpm publish 发布时,通过 --token 参数设置平台账号 token,bpm 获取该参数后跳过域账号鉴权,将其通过接口的 X-PLATFORM-TOKEN 头传递给物料库服务;

  3. 物料库服务查询数据库验证 token 有效性,获取对应的平台账号名称后执行发布操作。

    由于 token 长期有效,有效解决了平台使用公共账号发包的问题,并且平台账号限制了权限范围,只有平台账号为该包的 maintainer 才有权进行发布操作。

3.1.3. Monorepo

bpm 是一个全新的发布管理工具,而当前常见的 monorepo 管理工具(如 lerna、pnpm、rush 等)的发布功能基于 npm 体系,与其不兼容。在使用 bpm 的情况下,若要实现版本自动升级、Changelog 生成、批量发包等功能,往往需要结合项目编写额外脚本,使用成本较高。为改善这一状况,决定使 bpm 原生支持这些功能。但从头开发新的 monorepo 管理工具,不仅开发成本巨大,还会增加用户的学习成本。

经调研发现,开源工具 Changesets 能够满足大部分需求。Changesets 用于在 monorepo 项目中管理 npm 包版本和 Changelog,其工作流程将开发者分为项目维护者和开发者两类。开发者在项目开发完成后,为对应子项目添加 changesets 文件,维护者通过该工具消耗文件,自动修改包版本并生成CHANGELOG 文件,最后完成包的发布。

Changesets 可以满足大部分的场景,但仍然有以下的不足:

  1. changeset add 提交的变更信息不能直接作为 git commit 的 message 执行提交操作,需要手动再次执行 git commit,操作流程繁琐;

  2. 其 publish 功能基于 npm,不支持物料库的发布方式;

  3. 无法通过筛选参数过滤无需变更或发布的包,只能依据生成的 changesets 文件进行全量变更,灵活性不足。

为了解决上述的问题,我们没有将 Changesets 作为一个三方包直接引入,而是采用了源码集成的方式,并对上述的缺点直接做代码修改。前两个问题可以直接通过修改 Changesets 源码解决,但 filter 功能作为一个全新且较为复杂的模块,需要我们重新设计。

首先我们需要确定的是使用何种规则来做筛选。一般命令行会使用 glob 规则来做过滤,但该规则难以支撑复杂的包过滤场景。通过调研,我们发现 pnpm 的 --filter 是一个成熟且强大的过滤功能,支持以下过滤方式:

  1. 完整的包名匹配;

  2. 筛选依赖或被依赖的包;

  3. glob 规则匹配包名;

  4. git diff 比对获取变更的包。

除了功能强大外,使用 pnpm 的过滤规则还有以下优点:

  1. pnpm 在公司内使用程度高,使用其规则可以有效降低用户认知成本;

  2. pnpm 将该过滤能力封装成一个独立的包,接入成本较低。

因此 bpm 通过直接依赖的方式集成该过滤功能,优化后的发布流程为:在 bpm publish 时,根据是否设置 --filter 参数进行操作,若设置则对 workspace 包进行过滤,接着过滤未发布包,对依赖包进行排序后,提取出 changelog 中的发布描述,发布到物料库。

通过这些改进,bpm 的发布能力兼容了多种常见的 monorepo 管理工具(npm workspace、yarn、pnpm、rush、bolt),在这些工具管理的 monorepo 项目下,用户可直接使用 bpm publish 同时发布多个包,无需编写额外脚本。

3.2. 门户数据

Nexus3 提供的能力较弱,无法支撑起门户页面。因此,门户页面所需的数据和功能均由物料库服务实现。

3.2.1. 发布和数据

门户页面中 npm 相关数据皆来源于发布的包,因此在包发布流程中,提取关键元数据并存储到数据库,物料库再对这些元数据进行处理后在页面展示。具体流程为:

  1. bpm 发布 npm 包时,先运行相关钩子 script,将本地产物打包成 tgz 压缩包,并携带鉴权 session、发布描述、tag、git 地址等信息调用物料库发布接口;

  2. 物料库服务解压 tgz 包,获取 package.json,解析其中的 name、version、description、keywords 和 dependencies 等信息并存储到物料库数据库,同时获取 readme.mdchangelog.md 文档,解析为 html 文件后存储到 boss 中;

  3. 使用 nexus3 提供的平台账号,将 tgz 包发布到 nexus3 平台供用户下载;

  4. 发布完成后,调用企业微信通知接口,向关注该包的用户发送发布通知。

3.2.2. 下载统计

在整个系统架构中由 nexus3 承担 npm 包的下载功能,所以公司内部的 npm registry 直接指向该系统。但 nexus3 缺乏下载统计功能,而下载量是衡量 npm 包使用情况的重要指标。为实现准确统计,调研了多种方案:

  1. 通过 nexus3 的 repository 变更 webhook 统计,由物料库提供 webhook 地址,配置在 nexus3 系统中。当 repository 发生变更时,触发物料库的webhook,物料库根据 webhook 调用时提供的信息来统计各个 npm 包的下载量。但在实践中发现该 webhook 对于不同版本的下载,一天只触发一次,无法精确统计下载量;

  2. 通过日志平台的 slb accesslog 来统计每个 tgz 包的下载。logck 日志平台收集了经过 slb 的各个请求,且查看日志发现 nexus3 的日志采样率为100%。于是可以通过日志平台提供的 api 查询接口,每天定时查询日志来获取包的下载量。该方案需要保证采样率得一直是100%,但采样率由平台管控,无法保证全采样,数据准确性难以保障;

  3. Nexus3 平台每天定时将 access log 日志压缩上传到 boss 平台,物料库通过定时任务下载日志,解析其中的包名和版本号并统计存入数据库。该方案统计的数据准确且稳定,因此采用了该方案。

3.2.3. 项目依赖

相较于下载量这一笼统指标,项目依赖数能更精准地反映 npm 包在具体项目中的使用情况,对于依赖治理和版本升级策略制定具有重要意义。例如,当某个版本存在漏洞时,可依据依赖关系快速定位受影响项目并通知相关负责人进行升级。

为了精确追踪 npm 包在各项目中的使用情况,需要建立一套依赖数据收集机制。该机制需要解决以下问题:

1. 获取准确的依赖版本信息

挑战:尽管项目的 package.json 文件记录了依赖包信息,但通常只指定版本范围而非确切版本。

解决方案:通过解析 lock 文件(如 package-lock.json、yarn.lock、pnpm-lock.yaml 等)获取精确版本信息。lock 文件详细记录了项目实际使用的每个包的确切版本。通过开发通用解析模块 @jinkela/dependency,来支持多种 lock 文件格式的解析处理。

2. 确定数据收集范围与时机

挑战:公司内部代码分散在 gitlab 各仓库中,难以识别前端项目且权限受限。

解决方案:

  • 收集范围:聚焦于前端 CI/CD 平台上维护的前端项目,这些项目有明确的前端属性标识
  • 收集时机:选择在项目的 install 构建阶段进行依赖解析,这样做有两大优势:
  1. 确保能获取最新生成的 lock 文件,即使仓库中可能没有提交lock文件;

  2. 通过 install 流程后的 lock 文件反映了最新的依赖关系,避免使用可能过时的仓库版本。

3. 数据存储与应用

解析得到的依赖数据通过 API 接口上报至物料库进行集中存储和统计。这使我们能够构建双向查询能力:

  • 查询特定 npm 包被哪些项目使用;

  • 查询特定项目依赖了哪些 npm 包及其版本。

这套依赖收集系统为依赖治理、包版本升级策略等提供了数据基础,可以有效提升前端项目的依赖管理水平和风险应对能力。

3.3. 迁移

在物料系统开发完成后,需将数据和用户从 cnpm 迁移至物料库。

3.3.1. 迁移方案

从用户角度看,cnpm 迁移至物料库存在以下变更:

  1. 发包工具从 npm 到 bpm;

  2. 门户页面迁移到新的地址;

  3. lock 文件中下载链接变更。

其中,发包工具的变更,影响最大:

  1. 使用 lerna 等 monorepo 管理工具发包的,需要变更发布方法;

  2. 提供发布能力的平台,需要申请平台账号,变更发布工具。

而这些变更是需要一定时间完成改造的。为了避免直接下线 cnpm 导致提供发布能力的平台瘫痪,需要在下线前给平台时间完成改造,在物料库正式上线时,相关平台也可同步上线。为此制定了三步走的方案,

第一步:删档公测

  1. 准备迁移文档和公测文档;
  2. 向 cnpm 用户公示下线时间和迁移文档;
  3. 平台相关方在公测期间完成改造,等待上线。

第二步:数据迁移

  1. 公测期结束后,禁止物料库发布,清除测试数据;
  2. 将所有 cnpm 数据迁移到物料库和 nexus3。

第三步:正式上线

  1. 解除物料库发布限制;
  2. 将 npm 源切换到 nexus3 服务;
  3. 将原有 npm 门户地址重定向到新门户页面。

至此完成 cnpm 到物料库的迁移。

3.3.2. 数据迁移

cnpm 的数据主要包括存储在文件系统中的 npm tgz 格式包以及数据库中的元数据,这些数据将分别迁移至 nexus3 服务和物料库服务。其中,nexus3 负责包的存储与下载,物料库专注于元数据管理。

tgz包迁移

Nexus3 主要负责包的存储和下载,但同时也维护了部分元数据,使 npm 在下载时可以解析版本,获取下载链接。该部分元数据,有些可以从 tgz 包中的 package.json 中直接解析,比如版本、包名;而另外一些比如 tag,则需要从数据库获取。因此迁移 nexus3 系统,分成两步:

  1. 直接使用 tgz 包和从中提取出的 package.json,模拟 npm 包发布的流程,将所有 npm 包发到 nexus3 系统;
  2. 全部发布完成后,读取数据库中的 tag 信息,调用 nexus3 接口,修复包的 tag 数据。

数据库迁移

在物料库服务中建立与 cnpm 数据库的连接,读取相关数据并进行处理后,存入物料库数据库。

数据迁移中,最大的一个难题是账号的对齐。物料库采用公司统一账号鉴权,以域账号作为用户名,而 cnpm 的账号体系独立,用户名缺乏统一规范,在无账号映射数据的情况下,完整迁移账号难以实现。鉴于 cnpm 账号主要用于包 maintainer,若该数据丢失,包维护人在发包时会被系统拒绝,届时可提示其联系平台重新添加。因此,制定如下方案:

  1. 尝试从数据库迁移账号,读取 cnpm 账号名称,通过 hrcore 服务验证用户名是否为合法域账号,若合法则写入物料库服务;

  2. 迁移失败的,由维护人主动联系物料库添加 maintainer。

4. 其他物料

4.1. UMD

除 npm 包外,前端还存在通过将产物发布到 CDN,以 script 等方式引入的 js 文件等物料,统称为 UMD。在物料库建立之前,缺乏统一管理平台,其使用文档分散在众多 info 文档中,查找难度大。为实现前端物料的集中管理,降低用户检索难度,物料库将 UMD 纳入管理范畴。

4.1.1. 发布

UMD 物料首先需要明确产物结构。由于 NPM 仓库结构已被广泛认知,且多数 UMD 仓库也采用类似结构组织,因此物料库沿用该结构识别产物中的元信息和文档,并对 bpm 进行功能扩展,使其支持 UMD 发布。

UMD 与 npm 包的发布存在显著差异。npm 包发布后,使用方需 install 最新包并提交代码发布才会生效,具有一定延迟性且生效范围有限;而 UMD 发布是将代码直接覆盖到 CDN,页面通过链接引入后立即生效,涉及范围更广,这也使得 UMD 发布风险更高。

鉴于前端 CI/CD 平台已经成熟,具备不同环境发布验证、发布管控等功能,能够有效降低发布风险,因此将 UMD 发布流程整合到前端 CI/CD 平台,通过 UMD job 将产物发布到 CDN,并借助 bpm 将文档发布到物料平台。

4.1.2. 资源

UMD 物料的资源直接存储在 CDN 中,用户通过链接引入使用。对用户而言,要使用 UMD 物料,必须准确获取其链接地址,所以在物料库中展示 UMD 物料的 CDN 地址至关重要。但在 Dejavu 系统中,之前并未存储发布的资源地址,导致物料库无法从 Dejavu 获取关联资源。为解决这一问题,设计了一套 UMD 版本和资源地址关联的方案:

  1. 资源发布 job 在执行发布操作时,将构建 ID 和发布的资源地址存储到数据库中;

  2. 物料发布 job 执行 UMD 发布时,将 ID 传递给物料库进行存储;

  3. 物料库根据版本对应的构建 ID,到 CI/CD 平台查询资源地址。

    通过这套机制,物料库能够在平台上准确展示 UMD 物料的 CDN 链接地址,方便用户获取和使用。

4.2. 图标

图标物料与 NPM、UMD 物料存在本质区别,它不涉及代码维护和构建过程,而是直接将图标数据维护在平台中。因此,现有的 NPM 物料模块无法直接用于管理图标物料。不过,在物料库建立之前,公司已存在图标服务,物料库可通过集成该图标服务,实现图标物料的扩充。

为了保证用户拥有一致的体验,抹平不同平台使用的差异,决定使用以下方案:

  1. 将前端页面与物料库深度融合;
  2. 后端服务直接调用图标服务接口。

采用此方案后,绝大部分功能能够正常运行,但综合搜索功能存在问题。综合搜索旨在通过同一入口搜索多种相关物料,NPM 和 UMD 的物料数据存储在物料库中,可直接导入物料库的搜索引擎,但图标服务的数据不在物料库中,无法直接导入搜索引擎,也无法实时感知图标的新增和删除等变化。为此,设计了一套同步方案:

  1. 物料库启动时,调用图标服务接口,获取全量图标数据,并导入搜索引擎;
  2. 提供 webhook 接口,当图标服务发生图标更新操作时,通知物料库,物料库接收到通知后更新搜索引擎。

通过以上机制,物料库的综合搜索能力得以完善,能够实现对多种物料的高效搜索。

5. 搜索

随着大量 npm 包迁移至物料库,目前物料库已托管超过 3000+ 物料。对用户来说,通过搜索查找所需物料是最常用的方式,因此搜索功能的质量直接影响用户获取物料的效率。

5.1. 搜索引擎

对市面上适用于 nodejs 的常用搜索引擎进行了全面调研,从搜索功能支持、搜索性能、接入成本等多个维度进行评估:

综合考虑中文支持、接入成本和性能等因素,最终选定 MeiliSearch 作为物料库的搜索引擎。MeiliSearch 是一款基于 Rust 语言开发的开源搜索引擎,具有强大、快速、易于使用和部署的特点,其搜索和索引功能高度可定制,还提供了错字容忍、过滤器和同义词等开箱即用的功能,并且原生支持中文搜索。

在 MeiliSearch 搜索引擎的支持下,物料库的搜索功能得到显著增强,支持更丰富的搜索形式。用户通过关键词搜索,不仅能找到 npm、UMD 物料,还能搜索到图标以及外部的包,实现一站式物料查找。同时,物料库还支持条件筛选功能,用户可根据物料类型、keywords、维护人、scope 等多个维度进行筛选,快速定位到符合需求的物料。

5.2. 物料分类

通过搜索引擎,能够便捷地查找到各类物料资源,但往往难以准确判断这些物料是否适合我们的实际需求。一个科学合理的物料分类体系对于高效管理和复用物料至关重要。

传统物料分类主要依赖用户手动添加关键词(keyword)实现,这种方式缺乏统一标准和明确的维度划分,导致分类效果不佳。针对这一问题,对当前维护的所有物料进行了全面梳理,并从功能维度出发,构建了一套完善的四维分类标准。

1. 终端维度

主要根据不同的使用场景和运行环境进行分类,包括 H5、PC、小程序、服务端和开发端,帮助用户确定物料的适用范围。

2. 框架维度

聚焦于特定技术框架和生态系统,涵盖了当前前端主流框架,如 Vue 2、Vue 3、React、Solid、Web Component、Vanilla 以及其他框架。

3. 领域维度

面向特定业务领域,依据公司业务范围划分为基础、主站、OGV、直播等领域。其中,"基础" 领域用于标识适用于所有业务领域、使用范围广泛的物料,这类物料需要满足更高的标准,如提供详细的使用文档,并设置了专门的审核机制,以避免重复建设。

4. 功能维度

聚焦于物料的具体用途和作用,通过对现有物料的分析,建立了一套完整的功能分类体系,方便用户快速定位到所需功能的物料。

值得一提的是,这些分类并非固定不变,用户可根据实际需求向平台添加新的分类选项。

完成分类体系构建后,对平台首页进行了优化改造:

  1. 按照分类维度展示物料,使用户能够更直观地浏览不同类别的物料;
  2. 支持分类标签筛选,方便用户快速定位到感兴趣的物料;
  3. 仅展示已完成分类的物料,确保页面展示内容的规范性和可用性,推动用户对物料做分类。

同时,在物料详情页面,为维护人员提供了醒目提示,引导他们对物料进行合理分类,进一步提升平台整体物料的可发现性和可用性。

6. 文档

npm 包的文档形式较为单一,通常仅支持 readme.md 格式。然而,对于一些复杂的物料,如组件库,一份 readme.md 往往难以全面描述其功能和使用方法。因为组件库通常包含多个组件,为每个组件编写详细文档时,readme.md 的局限性就凸显出来。

部分 npm 包为解决 readme.md 文档的限制,搭建了专门的使用文档页面,并在 readme.md中嵌入跳转链接,引导用户前往该页面查看详细内容。但这种方式增加了用户的操作步骤,不够便捷,而且无法在物料库中直接向用户展示文档内容。

6.1. 外部文档

为解决上述问题,丰富文档形式,物料库引入了外部文档的概念,对 package.json 中的字段定义进行了拓展,新增了外部文档字段。例如:

当用户发布带有该字段的包时,物料库会提取该字段,并在物料详情页中通过 iframe 嵌入的方式,将外部文档页面展示给用户,使用户能够更方便地查看详细文档内容。

6.2. 产物预览

在查看 npm 包时,用户可能不仅关注其使用方法,还希望了解其实现原理。以往,用户需要先通过 npm install 将包下载到本地,然后在 node_modules 目录中查看相关代码,操作流程繁琐。为改善这一情况,设计了产物预览功能。

当用户查看某个版本的产物时,物料库服务会从 nexus3 服务下载对应版本的 tgz 包。tgz 包是一种压缩包,包含了各个产物文件以及目录结构。由于下载和解压操作较为耗时,因此在解压后,将解压数据进行内存缓存。当用户查看不同文件时,物料库服务可以直接从缓存中快速获取文件内容,实现文件切换的流畅体验,如同在本地操作一样。

产物中大部分是文本代码文件,为提升阅读体验,我们集成了 vscode 开源组件 monaco-editor,实现了代码高亮、显示行号等功能。但产物中也可能包含二进制数据,如图片,而 monaco-editor 不支持显示图片。为此进行了特殊处理:服务端提供返回二进制数据的接口,并根据文件后缀名设置合适的 content-type 字段;前端识别到文件名后缀为图片时,直接通过 img 标签,将 src 设置为二进制接口,从而实现图片的展示。

6.3. COSMOS2示例

通过查看文档了解组件的使用方式存在一定局限性,用户无法直观感受组件的实际效果,也不能自行调整组件参数查看变化。为解决这一问题,物料库引入了示例功能,用户可以在页面上直接查看组件的示例代码,并调整参数查看实际效果。物料维护者可以创建编写示例,作为使用文档的补充。

Cosmos2 是一个类似于 Codesandbox 的浏览器端沙盒运行环境,用于托管示例代码。前端示例代码主要由以下几个部分组成:

  1. 入口文件: 目前支持的入口文件为 /src/main.tsx、/src/main.ts、/src/main.jsx 或 /src/main.js;

  2. 模板文件: /index.html ,构建完成后会自动注入构建好的 js 和 css 产物;

  3. 依赖声明: /package.json 文件中的 dependencies 和 devDependencies 字段用于添加依赖声明。

在编写完成示例后,用户可在系统右侧直接看到运行效果,其运行流程如下:

  1. 解析 package.json 中的依赖声明,通过npm源

    递归下载依赖的包,实现在浏览器内存中的安装;

  2. 使用 esbuild-wasm 从入口开始转译代码,通过插件 onResolve 和 onLoad 解析 package.json,以支持导入外部包;

  3. 通过 document.write 将预览页面内容替换为本地构建结果。

7. 展望

通过对当前物料库中物料的梳理,发现公司内部物料存在功能同质化严重的问题,部分物料还缺少必要的文档,导致使用难度较大。

针对这些问题,未来物料库将从标准化和设置准入门槛两个方面进行优化,以减轻物料功能同质化现象,提高物料质量,为用户提供更优质、更易用的物料资源。

本文参考:

Changesets: 流行的 monorepo 场景发包工具(*zhuanlan.zhihu.com/p/427588430...

-End-

作者丨Chaoz

相关推荐
阿眠几秒前
vue3实现web端和小程序端个人签名
前端·小程序·apache
哎呦薇13 分钟前
从开发到发布:手把手教你将Vue组件上传npm
前端·vue.js
Z7676_15 分钟前
静态路由技术
服务器·前端·javascript
慧一居士16 分钟前
npm 和 npx 区别对比
前端
用户38022585982420 分钟前
vue3源码解析:生命周期
前端·vue.js·源码阅读
遂心_20 分钟前
前端路由进化论:从传统页面到React Router的SPA革命
前端·javascript
前端菜鸟杂货铺26 分钟前
前端首屏优化及可实现方法
前端
遂心_26 分钟前
React Fragment与DocumentFragment:提升性能的双剑合璧
前端·javascript·react.js
ze_juejin26 分钟前
ionic、flutter、uniapp对比
前端
咚咚咚ddd27 分钟前
WebView Bridge 跨平台方案:统一 API 实现多端小程序通信
前端·前端工程化