React skeleton loading component with SW CLI integration
npm install smarty-skeleton```
smarty-skeleton/ ← npm 包根目录
├── package.json ← npm 配置
├── tsconfig.json ← TypeScript 配置
├── vite.config.ts ← 构建配置
├── README.md
├── dist/ ← 构建产物
│ ├── index.es.js
│ ├── index.umd.js
│ └── index.d.ts
├── src/
│ ├── index.ts ← 导出组件和工具
│ ├── cli/ ← CLI 相关
│ │ ├── index.ts ← CLI 命令入口
│ │ └── swInjector.ts ← 注入/合并 SW 逻辑
│ ├── generate/ ← 骨架生成逻辑
│ │ ├── generateSkeleton.ts
│ │ ├── config.ts
│ │ ├── localforage.ts
│ │ └── requestIdleCallbackWithPolyfill.ts
│ ├── hooks/
│ │ └── useSkeletonLoading.ts ← 监听 SW 消息 / urls
│ ├── sw/
│ │ └── smarty-skeleton-sw.js ← 注入的 SW 文件
│ ├── SmartySkeleton.tsx ← React 组件
│ └── index.less ← 样式
└── bin/
└── smarty-skeleton-cli.js ← CLI 可执行文件
* 导出 SmartySkeleton 组件、generateSkeleton、配置、localforage 和 requestIdleCallback 工具
* 支持直接 npm 安装使用
* CLI 命令入口: 解析命令行参数,如 --urls、--loading
* swInjector.ts: 注入 SW 或合并已有 SW,初始化 urls 监听
* generateSkeleton.ts: 原来的骨架生成逻辑,保留缓存和动画逻辑config.ts
* : 默认骨架配置localforage.ts
* : 缓存工具requestIdleCallbackWithPolyfill.ts
* : 兼容浏览器的 requestIdleCallback
* 组件使用的 hook
* 订阅 SW 消息(fetch start/end)
* 根据 urls 控制组件 loading 状态
* 优先级:props.loading > urls
* 注入的 Service Worker 文件
* 监听 fetch/XHR 请求
* 匹配 urls 后向 clients 发送 start/end 消息
* 核心 React 组件
* 支持 loading prop、urls、缓存读取、骨架渲染和渐显动画
* 保留原缓存逻辑和骨架生成逻辑
* CLI 可执行文件
* 用户可在项目中执行命令注入 SW 并初始化 urls 监听
``
用户访问页面
│
▼
┌─────────────┐
│ SmartySkeleton │
│ 初始化 props │
└─────┬─────────┘
│
│ 是否传入 loading prop ?
├─────────────Yes──────────► 使用 loading prop,忽略 urls
│
No
│
▼
┌─────────────┐
│ 是否存在 SW? │
└─────┬─────────┘
│
│ Yes
▼
┌─────────────────────────┐
│ SW 已注册 │
│ 监听 fetch 请求 │
└─────┬───────────────────┘
│
│ No
▼
┌─────────────────────────┐
│ CLI 注入 SW 并注册 │
│ 初始化 urls 监听 │
└─────┬───────────────────┘
│
▼
┌─────────────────────────┐
│ 请求接口(fetch/XHR) │
└─────┬───────────────────┘
│
▼
┌─────────────────────────┐
│ SW 拦截请求 │
│ 检查是否匹配 urls │
└─────┬───────────────────┘
│
│ 匹配 urls ?
├─────Yes─────► SW 向 clients 发送 {type: FETCH_START, url} 消息
│
│ No
▼
┌─────────────────────────┐
│ SmartySkeleton 收到消息 │
│ useSkeletonLoading hook │
└─────┬───────────────────┘
│
▼
┌─────────────────────────┐
│ 设置 loading = true │
│ ske-innerwrap 显示骨架 │
└─────┬───────────────────┘
│
▼
┌─────────────────────────┐
│ fetch 接口返回响应 │
│ SW 发送 {type: FETCH_END} │
└─────┬───────────────────┘
│
▼
┌─────────────────────────┐
│ useSkeletonLoading hook │
│ 设置 loading = false │
└─────┬───────────────────┘
│
▼
┌─────────────────────────┐
│ generateSkeleton 渲染 │
│ ske-innerwrap 骨架淡出 │
│ ske-real-dom 渐入真实内容│
└─────┬───────────────────┘
│
▼
┌─────────────────────────┐
│ 缓存 skeletonDOM 到 │
│ localforage │
└─────────────────────────┘
1. props.loading 优先,直接决定组件 loading 状态props.loading
2. 如果没有 ,通过 SW 消息监听匹配的 urls` 控制 loading
3. 骨架生成、缓存、动画逻辑保持原样
1. CLI 检测项目是否已有 SW
* 如果存在,合并监听逻辑
* 如果不存在,注入新的 SW 并注册
2. 初始化 urls 监听,将匹配请求消息发送到客户端
3. 客户端 hook 根据消息更新骨架 loading 状态
---