本文件是 AI(Claude Code / FmodeCode)在本仓、或引用本仓规则时的第一入口。 写任何 Lit 前端代码前,先读本文件,再按下表索引到具体规则篇。 源稿:
.claude/_lit-dev-manual.md(用户提供的《Lit 原生 ESM 无构建开发最佳实践》)。
.js 直接上传 OBS,浏览器原生 ESM 执行。lit、@lit-labs/* 等运行时依赖一律从 FMODE Repose 公共 importmap 引入,禁止把依赖源码拷进业务仓、禁止业务仓 import 裸 node_modules。fetch、禁止写复杂业务逻辑;服务禁止触碰 DOM。| # | 规则篇 | 内容 | 何时读 |
|---|---|---|---|
| 1 | architecture.md | 整体架构、分层职责、运行流程、部署拓扑 | 起项目 / 定架构 |
| 2 | project-structure.md | 目录规范、命名、文件摆放、二级路径 base | 建目录 / 放文件 |
| 3 | components.md | LitElement 组件规范、Shadow DOM、属性/事件、Slot | 写组件 |
| 4 | services.md | Service 分层、Signal 状态、单例、可单测 | 写服务 / 状态 |
| 5 | context-di.md | @lit-labs/context 令牌与 provide/consume |
做依赖注入 |
| 6 | routing.md | History 路由、守卫、404(子路径部署自写 utils/router.js) |
做路由 |
| 7 | tabs-keepalive.md | 后台多标签 + KeepAlive(实例常驻) | 做后台壳 |
| 8 | http-utils.md | 原生 Fetch 封装、token 拦截、错误处理、utils | 写请求 / 工具 |
| 9 | deployment.md | FMODE Repose 依赖托管 + OBS+CDN 业务部署 + importmap | 上线 / 配依赖 |
| 10 | pitfalls.md | CORS / 版本冲突 / 302 陷阱 / base href 等坑位 | 排查问题 |
| 11 | modules/ | 功能模块 / 通用能力 / 业务模块 划分最佳实践 | 模块拆分 |
| 12 | routing-best-practices.md | 子路径部署路由实战:base 三处同源 / new URL 丢前缀 / 弃用 @lit-labs/router / CDN 刷新假成功 / 验收不能只 curl |
做路由 / 子路径部署 / 上线验收 |
| 13 | retrospective.md | 对标 Angular zoneless 的技术复盘 | 理解选型理由 |
浏览器打开 URL → CDN 回退规则把不存在的路径 200(非 302) 返回 index.html → index.html 加载 公共 importmap(指向 FMODE Repose)→ 加载 app.js → import lit 依赖 → 初始化 Store / 路由 / 根组件 → 渲染。全程零编译。
| 关注点 | 选择 | 备注 |
|---|---|---|
| 视图 | Lit 3.x LitElement |
Shadow DOM 隔离 |
| 全局状态 | @lit-labs/signals + Service 单例 |
跨组件共享 |
| 组件本地状态 | Lit @property / @state |
弹窗、输入框 |
| 依赖注入 | @lit-labs/context |
令牌 + provide/consume |
| 路由 | 自写 utils/router.js(History 干净 URL) |
子路径部署禁用 @lit-labs/router(全局 <a> 拦截 + 未剥前缀 pathname 会污染路由);根部署可选它 |
| 请求 | 原生 fetch 薄封装 |
不引 axios |
| 持久化 | localStorage 薄封装 |
一次性配置 |
| 部署 | OBS + CDN | 无构建直传 |
| 场景 | 方案 |
|---|---|
| 全局业务状态,多页共享(登录态、字典、权限) | Signal Service + Context 注入(首选) |
| 组件本地 UI 状态(弹窗开关、表单输入) | Lit @property / @state |
| 简单应用不想引 signals | EventTarget 简易 Store + Context |
| 一次性持久化配置 | localStorage 封装(utils/storage.js) |
⚠️ 两套响应式必须分开:跨组件全局业务状态用 Signal;组件内部 UI 用 Lit property。混用会导致更新时机错乱。
.js 必须 text/javascript,CORS 放行业务域名),全业务共享一份公共 importmap。obsutil 同步 src/ 到 OBS(华为云 obs://www-fmode.cn/<project>/,南一端点),public-read,CDN 指向 fmode.cn/<project>/,最后刷新 CDN。<base href="/<project>/">,且 <base href> == OBS 上传前缀 == importmap 路径前缀(同一变量派生 + 脚本硬校验),否则相对 JS 404。index.html 且状态码 200」,严禁 302/301(否则地址栏被改写、微信 OAuth 回调失败)。type:directory + domain_id 对号入座;SDK 返回的 refresh_task 是字符串(不是 .id),失败须退出非 0(否则假成功)。curl 首页 200 —— 须跑模块图爬取(200 + text/javascript)+ 深链接 200 + 真实浏览器。详见 deployment.md 与 routing-best-practices.md。
kebab-case.js,类名 PascalCase,自定义元素标签 kebab-case(必须含连字符)xxx-service.js,类 XxxService,单例导出 export const xxxService = new XxxService()xxx.js,导出纯函数routes/page-xxx.js,标签 <page-xxx>index.html:<base> + <script type="importmap" src="<公共importmap>"> + <script type="module" src="./app.js">components/ routes/ services/ utils/app.js:provide 全局 Service + 挂载 Router + 根组件SignalWatcher(LitElement) + consume Serviceobsutil sync + CDN refresh具体脚手架:用全局技能
fmode-code-lit(npx fmode-code-lit@latest workspace)一键生成。