☰
Plasmic 单仓库开发指南:读懂根目录 CLAUDE.md,快速上手 platform、packages 与 plasmicpkgs
2026/10/8 7:51:55 网站建设 项目流程
  • 低代码
  • 前端
  • 后端

【免费下载链接】plasmic

Visual builder for React. Build apps, websites, and content. Integrate with your codebase.

项目地址:https://gitcode.com/gh_mirrors/pl/plasmic
点击查看免费下载

导读

本文以 Plasmic 开源仓库根目录的 CLAUDE.md 为主线,系统梳理这个 monorepo 的目录结构、根目录集中管理工具、技术栈与 AI 辅助开发工作流约定。读完本文,你将理解 Plasmic 平台应用(platform/)、SDK 包(packages/)与代码组件包(plasmicpkgs/)三大板块的边界与协作方式,掌握pnpm工作区、版本管理、代码格式化的实际机制,并熟悉在此仓库中开展开发、测试与提交的正确姿势。

一、CLAUDE.md 是什么:AI 辅助开发的"仓库宪法"

在 Plasmic 仓库根目录,CLAUDE.md是一份面向 AI 编码助手的规范指令文件。仓库中 AGENTS.md 是它的符号链接(symlink),两者指向同一份内容。项目约定明确:修改时只编辑CLAUDE.md,绝不直接编辑AGENTS.md,以避免两份文件内容漂移。

这份指令文件的价值在于它锚定了整个仓库的关键事实,让 AI 助手(以及新加入的开发者)在"最省力"的前提下掌握:

  • 根目录集中管理哪些工程化资产;
  • 四个核心目录各自承担什么职责;
  • 采用什么技术栈、包管理器与测试框架;
  • 提交代码前有哪些流程与前置条件;
  • 搜索文件时应避开哪些目录。

此外,指令是按目录作用域叠加的:距离某个路径最近的CLAUDE.md对该路径生效,并在根文件基础上做增量补充,而非互相矛盾。例如平台侧的 platform/wab/CLAUDE.md 就专门针对 WAB(Web Application Builder,Plasmic Studio 核心应用)补充了关键命令与编码约定,根文件明确要求"修改platform/wab下任何内容之前,先读它"。

二、根目录的集中管理资产

CLAUDE.md 明确指出:本目录是 monorepo 的根,绝大多数开发在各自包内进行,但根目录负责若干集中管理的工程化事项,逐项展开如下。

package.json:统一依赖版本

根 package.json 中存放的是"希望全仓库使用同一版本"的公共 devDependencies,例如:

  • eslint、eslint-config-prettier、eslint-plugin-react、eslint-plugin-react-hooks等 lint 工具链;
  • prettier与prettier-plugin-organize-imports格式化链;
  • vitest、tstyche、storybook及@storybook/*组件库测试链;
  • typescript、tsx、vite、esbuild、lerna、nx、knip等构建与工程工具;
  • husky、lint-staged等 git 钩子工具。

其中的"packageManager": "pnpm@11.10.0"声明了仓库统一使用的包管理器版本,配合 pnpm-workspace.yaml 定义整个工作区。依赖版本大量使用catalog:引用——这是 pnpm 的目录(catalog)特性,版本号集中在 pnpm-workspace.yaml 的catalog段统一维护(例如typescript: "5.2.2"、react: "18.3.1"、vitest: "4.1.10"),避免各包重复维护版本号。

build.mjs:统一的构建脚本

build.mjs 是packages/的通用构建脚本,其头部注释点明职责:"跨包一致地校验 package.json 并构建产物"。从源码结构看(build.mjs),它主要完成三件事:

  1. 接收入口文件路径作为首个命令行参数,并解析--use-client、--no-esm、--no-mjs、--watch等选项;
  2. 根据入口文件名生成期望的 package.json,与实际 package.json 比对校验(包括 react-server conditional exports),保证产物导出结构符合约定;
  3. 调用 esbuild 构建 bundle,并借助@microsoft/api-extractor对 dts 进行 rollup,产出统一的类型声明。

这解释了为什么所有packages/下包的产物形态高度一致:构建行为由根目录脚本集中治理。

.eslintrc.js:共享 lint 配置

根 .eslintrc.js 定义了共享的 ESLint 配置,其中最有特色的是按目录区分 client/server/test 文件的规则(.eslintrc.js):

  • clientFiles:platform/wab/src/wab/main.tsx与src/wab/client/**;
  • serverFiles:src/wab/server/**;
  • testFiles:**/*.spec.ts(x)、**/*.test.ts(x)、**/*.stories.tsx、**/__testonly__/**、**/__mocks__/**等。

它还实现了一个"overlay"查找机制(findOverlayTargets,.eslintrc.js):自动识别foo.external.ts、foo.public.ts这类占位文件(分别用于 public 与 enterprise 同步时替换真实实现),确保 lint 覆盖到这类特殊文件。

vitest.root.ts:共享单测配置

vitest.root.ts 是packages/与plasmicpkgs/共用的 Vitest 配置,由根脚本pnpm test(vitest run --config vitest.root.ts $TEST_CWD)驱动。文件注释说明了两个设计决策:

  • 命名为vitest.root.ts而非vitest.config.ts,是因为 Vitest 会向父目录搜索配置——若在根放一个普通vitest.config.ts,没有自己配置的包就会继承它去跑整个工作区;
  • 配置以projects形式列出packages/、plasmicpkgs/、plasmicpkgs/commerce-providers下所有含 package.json 的目录(packageDirs辅助函数动态扫描),同时故意不用packages/*通配,以避免把plasmicpkgs/README.md之类的非包文件误当项目。每个包仍保留自己的 vitest 设置(环境、setup 文件等)。

knip.ts:未使用依赖检查

knip.ts 是 knip 的配置,用来排查未使用的依赖,通过根脚本knip:deps(NODE_ENV=test knip --include dependencies)运行。它ignoreWorkspaces了根、packages/**与plasmicpkgs/**,而把检查重点放在platform/下的应用上,并为platform/wab等 workspace 指定 entry/project 文件模式及ignoreDependencies白名单(如coffeescript由 pegcoffee 使用、dotenv由tools/run.bash使用,需显式豁免)。

三、关键目录:一个 monorepo 的四层结构

CLAUDE.md 用一句话定位了这个仓库:"Plasmic 是一个开源的可视化 Web 构建器",并给出四个关键目录的职责划分:

目录内容定位
platform/WAB、img-optimizer 等平台应用构成 Plasmic 平台本身
packages/集成 Plasmic 的 npm 包SDK,如 loader-react、loader-nextjs、host
plasmicpkgs/提供代码组件的 npm 包内置代码组件库
examples/各类参考实现示例工程

逐一核对仓库实际内容:

  • Platform(platform/):除核心的wab(Plasmic Studio 主应用,含 React 客户端、主应用服务器、codegen 服务器与各种工具)外,还有canvas-packages、host-test、integration-tests、live-frame、loader-bundle-env、loader-html-hydrate、loader-tests、react-renderer、react-web-bundle、sub等平台支撑应用。这一层单独维护自己的package.json与pnpm-workspace.yaml(platform/package.json、platform/pnpm-workspace.yaml),是仓库中体量最大的一块。
  • SDK packages(packages/):涵盖auth-api、auth-react、cli、create-plasmic-app、data-sources、host、loader-core、loader-edge、loader-fetcher、loader-gatsby、loader-nextjs、loader-react、loader-splits、nextjs-app-router、prepass、query、react-web、react-web-runtime、watcher等。其中packages/react-web提供运行时渲染内核,packages/host承载registerComponent等注册 API。
  • Plasmic packages(plasmicpkgs/):提供开箱即用的代码组件,如antd/antd5、chakra-ui、radix-ui、react-aria、react-chartjs-2、tiptap、contentful、framer-motion、google-maps、keen-slider、plasmic-basic-components等几十个包,还包含commerce-providers(Shopify、Swell、Saleor、Commercetools 等电商提供商)。
  • Examples(examples/):nextjs-example、plasmic-cms-nextjs、supabase-auth-nextjs-pages-loader、react-dnd、scroll-aware-navbar等大量参考工程,演示如何在真实框架中接入 Plasmic。

四、技术栈与工程工具链

CLAUDE.md 明确列出的技术栈如下:

  • 基础设施:Docker、k8s、Terraform;
  • JavaScript 工具链:asdf 与 pnpm;
  • 语言:Node.js、TypeScript;
  • 库:React、MobX、TypeORM、Vitest、Playwright、Storybook。

仓库中的佐证随处可见:.tool-versions 声明nodejs 24.4.0、python 3.10.13、terragrunt 1.0.4,正是 asdf 的版本管理文件;根与 platform 两侧各有一份 pnpm-lock.yaml;docker-compose.yml 定义了本地基础设施(Postgres 等服务);packages/下普遍配置 Vitest 与 Storybook,平台侧loader-tests使用 Playwright 做端到端测试。

工作区边界值得注意:根 pnpm-workspace.yaml 的packages:段只收纳packages/*、plasmicpkgs/*、plasmicpkgs/commerce-providers/*与plasmicpkgs-dev,并显式排除packages/loader-angular、packages/loader-svelte、packages/loader-vue、packages/plasmic这些"无版本的弃用桩包";而platform/是独立的一层 workspace(见 platform/pnpm-workspace.yaml)。该文件还通过catalog/catalogs统一依赖版本、overrides钉住冲突版本(如 storybook 相关 shim 钉在 8.5.5)、allowBuilds控制生命周期脚本(如 esbuild/sharp 禁止构建)、shamefullyHoist: true与linkWorkspacePackages: deep调整链接行为——这些都属于根目录集中治理的一部分。

五、AI 助手与开发者的工作流约定

CLAUDE.md 后半部分是面向 AI 助手的具体操作纪律,也是日常提交代码时必须遵守的流程。

沙箱检查

文档开头的 "Sandbox" 一节提醒:你可能身处一个受限沙箱环境,应参考safehouse.sb沙箱配置。需要说明的是,当前仓库镜像中未包含该文件(docs/下仅有贡献相关文档),但从根 package.json 的脚本可以看出这套约束的落地形态:

  • pnpm claude依次执行check-devcontainer(要求必须在 devcontainer 中运行)、check-no-fs(确认无法读取~/.plasmic/secrets.json与~/.ssh/私钥)、check-no-network(确认无外网),然后以--dangerously-skip-permissions --mcp-config=.claude/.mcp.json启动 claude;
  • pnpm claude-safehouse只做check-no-fs检查,用于较宽松的沙箱。

也就是说,CLAUDE.md 的沙箱提醒与根目录的check-*脚本共同构成一道"安全门",防止 AI 助手在不受控环境中接触密钥或外网。

提交前的格式化与 git 钩子

文档对格式化给出的约定是:不要操心样式/格式——所有文件都会在 git hooks 阶段被统一格式化为同一风格,该钩子由 husky 管理,生成物是 gitignore 的.husky/_目录。

这里隐含一个关键前提:在一个全新的 worktree 中,.husky/_尚不存在,git 会静默跳过所有钩子。因此文档明确要求:在第一次提交前,先在 worktree 根目录运行pnpm install,让 husky 生成钩子目录。根 package.json 中的"prepare": "husky"正是安装阶段触发 husky 初始化的入口,配合.lintstagedrc.js对暂存文件执行 eslint/prettier 修复。

搜索文件时的边界

文档规定:搜索文件时几乎不要翻 node_modules/ 及其他被 gitignore 的文件,除非有明确理由。这一点配合 .gitignore 生效,既保护搜索效率,也避免把依赖代码当作仓库事实。

六、平台子目录的实践补充:以 platform/wab 为例

根 CLAUDE.md 的"就近生效"原则在platform/wab体现得最充分。platform/wab/CLAUDE.md 面向 WAB(Plasmic Studio 核心应用)补充了可复制的日常命令:

# 在仓库根目录完成整体初始化(setup 必须从根目录执行) cd ../.. && pnpm setup-all # 启动完整开发环境(前端 + 后端 + host-server),访问 http://localhost:3003 pnpm dev # 运行单元测试 pnpm test # 更新单元测试快照 pnpm test:update-snapshots # TypeScript 类型检查 pnpm typecheck # ESLint(根目录使用 .eslintrc.js) pnpm eslint-all # 构建生产前端 pnpm build

此外它给出三条与根文件互补的编码约定(platform/wab/CLAUDE.md):

  1. 写工具函数前先查src/wab/shared/common.ts——那里是共享"杂货袋"(ensure、assert、withoutNils、maybe、only、tuple、spawn、xGroupBy等),src/wab/commons/与 lodash 覆盖其余需求,不要重复造轮子;
  2. 用ensure(x, msg)与assert(cond, msg)取代非空断言(!)与未检查的 cast,让不变量在破坏处立即失败并给出期望信息;
  3. 对模型类的分派用switchType(...)而非instanceof链,并以.result()收尾——这样只要新增模型类未处理,类型检查就会失败,而不是运行时静默穿透;原生switch/if-else链则用assertNever/unreachable达到同样目的;
  4. 不完整或有风险的功能必须藏在 devflag(src/wab/shared/devflags.ts)后面,只有"部署即对所有人生效"的用户可见行为变更才允许不加门控直接发布。

这套约定解释了 WAB 这种数千文件规模代码库为何能长期保持可维护性:共享工具集中、类型系统兜底、新功能渐进放量。

七、版本管理:@plasmicapp 包如何保持同步

CLAUDE.md 专门指出一个常见问题:包版本不匹配或重复安装。关键事实与机制如下:

  • @plasmicapp各包可能互相依赖,且始终以精确版本(exact version)依赖彼此,确保整组包永远同步、不会出现错配组合;
  • @plasmicapp/host这类包还必须被 dedupe,因为registerComponent等能力依赖全局变量与副作用,多版本共存会导致"用错实例";同时各包类型紧密耦合;
  • npm 与 yarn 很容易让你落入版本错配/重复的陷阱,应使用npm list确认唯一且 deduped 的版本;问题还可能"粘性"残留(npm/yarn 是有状态的),必要时借助npm dedupe,或删除重装 Plasmic 相关包(含@plasmicpkgs包)并重置 package-lock.json/yarn.lock 来解除卡死;
  • 与@plasmicapp相反,@plasmicpkgs(内置代码组件包)把@plasmicapp包声明为peer dependency 且用范围版本,以给开发者选择核心包版本的一定灵活性。

关于版本递增,文档补充了两个事实:精确版本不意味着每个包每次发布都升版本,只有包自身或其依赖变化时才会递增;递增由部署脚本运行lerna version patch --exact...自动完成,该命令检测包自上次 git 打标签发布以来是否变化。从根 package.json 可以看到lerna作为 devDependency 存在,lerna.json 配置了版本管理参数;内部dependencies/devDependencies声明为workspace:*,在 pack 时由pnpm publish替换为精确版本——这正是 pnpm-workspace.yaml 中linkWorkspacePackages: deep等设置的配套机制。

八、贡献与许可速览

  • 贡献指南见 CONTRIBUTING.md,平台侧更细的入门文档在 docs/contributing/platform/00-getting-started.md(含配置工具链 01-config-tooling.md、集成 02-integrations.md、Figma 03-figma.md);
  • 许可采用双轨制:platform/之外全部内容遵循 MIT(见 LICENSE.md),platform/遵循 AGPL(见 LICENSE.platform.md)——CLAUDE.md 明确记录了这一点,贡献代码前应据此判断自己改动的授权边界。

结语

根目录的 CLAUDE.md 虽然篇幅不长,却是理解整个 Plasmic monorepo 的最小必要入口:它划定了根目录集中治理的工程资产(依赖、构建、lint、测试、依赖检查),定义了platform/、packages/、plasmicpkgs/、examples/的职责边界,规定了 pnpm 工作区与版本同步的底层机制,并为 AI 助手和开发者提供了沙箱、格式化、文件搜索等可执行的工作流纪律。在此基础上再叠加各子目录(尤其是platform/wab)的局部指令,你就能在这个大型仓库中快速定位代码、安全地开展开发与提交。

  • 低代码
  • 前端
  • 后端

【免费下载链接】plasmic

Visual builder for React. Build apps, websites, and content. Integrate with your codebase.

项目地址:https://gitcode.com/gh_mirrors/pl/plasmic
点击查看免费下载

相关推荐

上一篇:Jr多语言支持:如何创建国际化静态网站
下一篇:如何在 Minecraft 服务器中快速部署 CoreProtect:终极数据保护与回滚指南 🛡️

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询