读 fe-awesome-demos:让旧 Demo 成为今天可运行的练习
本文目录
逐项梳理 14 个基础、CSS、插件、QA、Canvas、框架、构建与设计模式目录,附安全隔离和可验证动画示例。
本文是对 BryanAdamss/fe-awesome-demos 的原创导读。项目来自 腾讯新闻前端团队 2022 年的 25 个 Awesome 项目推荐;这里按 2026-10-09 能核实的仓库内容重新整理,不转载原 README 或其收录的第三方作品。
仓库内容地图
- DaNei、Dmd、MiaoV、Zns:基础与中级练习
- CssSecrets:CSS 视觉技巧
- Plugins、Practice、QA:组件实验、实战与问题记录
- Canvas:绘图与动画
- AngularJS、Vue、Webpack:历史框架与构建实践
- Sjms:设计模式及其适用情境
怎么读才有收获
Demo 的价值在于短反馈循环。打开每个目录先确认入口和依赖;跑不起来时先判断是旧 API、依赖失效还是浏览器安全策略改变。不要为了运行旧示例而在生产环境关闭安全限制。
固定版本与目录全景
本文按 2020-09-27 的 README 提交 db7f353ef5d5697985d61a510fbee075c5c6bca3 还原练习范围。README 为 12,008 字节、144 行,含 14 个主题目录、87 条 Markdown 链接引用和 86 个不同目标。GitHub 没有声明 SPDX 许可,固定版本根目录也没有 LICENSE,因此这里逐项整理目录主题与学习要点,不镜像整份 README 或其外链编排。仓库由 BryanAdamss/fe-awesome-demos 转移到 awesome-vault/fe-awesome-demos;不少目录链接仍指向旧 SourceSave 仓库,打开前要检查跳转和可用性。
| 原目录 | 原有内容范围 | 今天可练到的能力 |
|---|---|---|
| DaNei | 教程 Demo、jQuery 插件、jQuery 插件开发最佳实践、AMD/CMD/CommonJS 兼容、尺寸与位置 | 插件契约、模块格式差异、布局测量 |
| Dmd | 常用代码片段 | 把零散片段改造成有输入边界和测试的函数 |
| MiaoV | 妙 V 教程练习 | 跟随旧教程复现,并标记依赖与浏览器差异 |
| Zns | 智能社教程练习 | 基础交互、DOM 与渐进式调试 |
| CssSecrets | 《CSS 揭秘》示例和演示入口 | 由视觉目标推导 CSS,而不是背效果代码 |
| Plugins | jQuery 插件模板、倒计时、拖拽、本地分页、JSONP、移动手势 | 生命周期、事件清理、坐标与请求安全 |
| Practice | 动画帧、原生模块、Handlebars、类型判断、AMD 模板、模板引擎、Flex、PhotoSwipe、移动端 fixed/input、bootstrap-table API、自定义滚动条、DES3、地图坐标、合成层 | 浏览器行为、布局、媒体交互、性能和兼容策略 |
| QA | 数组去重多种实现、数组/对象浅拷贝、深拷贝与 JSON 变体、遍历/是否改变原值、随机数、极值、DOM Ready | 用语义和边界选择实现,而非只记面试答案 |
| Canvas | 在线教程总结与 MDN Canvas 学习入口 | 坐标系、像素比、绘制循环、输入与资源释放 |
| AngularJs | 官方指南、课程 Demo、招聘网站案例、教程总结、TodoMVC | 识别 Scope/指令/依赖注入等历史架构 |
| Vue | 官方教程、Vue 音乐 App、Vue CLI 注释总结及配套文章 | 组件、响应式、路由/构建与播放器状态边界 |
| Webpack | 官方指南、多页应用、WebpackTemplate 脚手架及配套文章 | entry/output、资源依赖、代码拆分和发布缓存 |
| Sjms | 设计模式导读、惰性单例、策略模式、可先订阅的命名空间观察者 | 模式的约束、可替换行为与事件生命周期 |
| 其他 | 个人博客、PC/移动端项目脚手架、Webpack 多页脚手架、Vue 脚手架 | 从 Demo 走到目录组织、构建与交付 |
原 README 把目录描述为由易到难的练习集合;其中不少目录仅有少量示例,表格保留的是主题覆盖面,不暗示每个主题都有完整教程、可运行测试或现代依赖。
把每类案例读成工程问题
插件、工具函数与模块格式
jQuery 插件练习适合分析初始化契约:是否支持多个元素、默认配置如何合并、重复初始化是否幂等、实例状态放在哪里、销毁时如何移除事件和定时器。倒计时要区分墙上时钟与单调计时;浏览器标签页被挂起后,应根据目标时间重新计算剩余量,不能把每次 setInterval 当作准确时钟。拖拽要考虑 Pointer Events、触摸、坐标缩放、指针捕获、键盘替代和取消。分页组件需区分本地完整数据与服务端分页,不能把两个页码模型混用。
旧示例里的 AMD、CMD、CommonJS 反映当时浏览器模块生态。今天读它们可以理解依赖声明和加载顺序如何演进到 ESM;新项目应先看平台原生模块、目标运行时和工具链,不要为“兼容所有格式”引入不再维护的包装层。JSONP 只能通过插入 script 读取可执行响应,无法像 fetch 一样控制请求方法和响应体;不要把用户输入拼进回调名或脚本地址。跨域数据优先使用正确配置的 CORS。
CSS、移动端与图形
《CSS 揭秘》类 Demo 的学习方式是从视觉约束反推布局、渐变、边框、阴影和裁切,再检查缩放、深色模式、强制颜色和减少动态效果。Flex 示例要验证内容变化时是否溢出;自定义滚动条不能破坏键盘滚动和系统滚动偏好。移动端 fixed/input 案例要分别检查软键盘弹出、Visual Viewport、浏览器地址栏伸缩、安全区和焦点滚动;不要只复制早期机型的高度补丁。
Canvas 案例把 CSS 尺寸、backing-store 像素和 devicePixelRatio 分开:按屏幕像素比缩放绘图缓冲区,同时为超大画布设像素预算。Pointer 事件应记录笔迹并支持触摸;动画使用请求帧时间戳推进,页面不可见时可暂停或降低工作量;卸载时取消动画、断开 ResizeObserver 并清空引用。图片合成还要验证跨域来源,否则画布可能被污染而无法导出。
QA 题目不能只留一个“标准答案”
数组去重的朴素查找、从第二项开始扫描、filter、ES 集合、对象键和排序法,时间/空间成本、稳定顺序和数据类型行为都不同。对象键法会遇到原型键、数字与字符串同名、对象引用和 NaN 等边界,不能作为通用答案。数组浅拷贝的 slice、concat、展开语法和 Object.assign 都只复制一层;深拷贝的 JSON 往返会丢掉 undefined、函数、循环引用、Map/Set 与特殊对象语义,兼容版实现需要先定义受支持的数据类型。
遍历练习还要说明是否跳过稀疏空位、是否访问继承属性、是否改变原数组。随机数应使用整数区间的无偏采样;普通抽签与安全令牌不能共用随机源。最大/最小值要处理空数组、非数字、超长参数展开和比较语义。DOM Ready 的早期兼容分支是历史背景;现代页面通常利用 defer、模块脚本或 DOMContentLoaded,并确保注册时事件尚未错过。
框架、构建与设计模式
AngularJS 项目覆盖官方 Demo、课程、招聘场景和 TodoMVC,适合研究依赖注入、Scope、指令和路由如何组织 UI。AngularJS 已于 2022 年 1 月结束官方支持,只把它当作维护旧系统和理解历史设计的材料;新项目应评估仍受支持的框架,迁移时先补行为测试,再逐步替换边界。
Vue 示例从官方基础、音乐 App 到 CLI 注释,能练组件拆分、列表/详情状态、播放队列、异步数据、路由和构建产物。音乐 Demo 不应把播放状态散落在多个组件,也要处理音频加载失败、用户手势播放限制、切页后的资源和小屏控制。旧 Vue CLI 配置适合和现代构建方式对照,不等于当前脚手架建议。
Webpack 多页案例适合区分页面入口、共享依赖、公共资源、hash 缓存和开发/生产配置;脚手架要验证干净安装、开发启动、构建、静态部署和回滚。不要把某个历史配置逐行搬进新仓库;先量构建速度、产物大小、缓存命中和页面加载,再决定升级或替换。个人博客/PC 移动项目模板也应检查锁文件、环境变量、错误页、访问性、发布路径与依赖许可。
惰性单例解决“至多创建一次”的对象生命周期问题;策略模式把可替换算法从条件分支中分离;带命名空间且支持先订阅后发布的观察者模式则强调事件订阅何时建立、缓存事件是否重放、如何取消订阅和限制内存。它们是取舍工具,不是为了套模式而增加抽象层。
一个可验证的动画循环
把 requestAnimationFrame 和取消函数注入后,循环可以在浏览器里使用原生 API,也能在测试中用假调度器验证重复启动和停止,不依赖真实屏幕刷新:
function createAnimationLoop(draw, requestFrame, cancelFrame) {
let active = false;
let frameId = null;
const tick = (time) => {
if (!active) return;
draw(time);
if (active) frameId = requestFrame(tick);
};
return {
start() {
if (!active) { active = true; frameId = requestFrame(tick); }
},
stop() {
active = false;
if (frameId !== null) cancelFrame(frameId);
frameId = null;
},
};
}
调用方在组件卸载时必须调用 stop();绘制逻辑用传入的时间戳计算 delta,避免固定每帧增加一个像素导致高刷新率设备更快。真实页面还要决定后台标签页策略,并给动画提供可暂停、可恢复的控制。
把旧 Demo 安全地放进在线实验室
不能把第三方 HTML 直接拼进博客主站或用 innerHTML 注入脚本。在线体验应部署到与博客隔离的独立 origin,用 <iframe sandbox> 默认拒绝权限,只按需要开放脚本;不要给同源不可信代码同时开放 allow-scripts 和 allow-same-origin。表单提交、弹窗、下载、顶层跳转、摄像头、麦克风、剪贴板和任意网络默认关闭。主页面与实验 iframe 通信时使用固定 targetOrigin,接收端同时校验 origin、source、消息 schema、大小和速率。
一个实验清单可以声明被允许的最小能力;它不是安全沙箱本身,真正的隔离仍要由独立站点、HTTP 响应头、iframe sandbox 和服务端静态资源策略共同完成:
{
"id": "canvas-frame-loop",
"title": "Canvas 动画循环",
"sourceCommit": "db7f353ef5d5697985d61a510fbee075c5c6bca3",
"runtime": "isolated-iframe",
"sandbox": ["allow-scripts"],
"permissions": [],
"allowedMessages": ["ready", "resize", "report-error"]
}
运行前记录依赖、入口、预期行为和退出方式;运行时设置 CPU/内存/网络边界与超时;退出后移除 iframe、监听器、定时器和对象 URL。沙箱失败时提供源码与静态截图回退,不要为了“可运行”移除浏览器保护。
由旧仓库转成现代练习的顺序
- 基础与数据:从代码片段和 QA 主题开始,为空值、重复值、原地修改和复杂度写契约及测试。
- 布局与交互:改造 Flex、CSS 视觉、拖拽、分页和手势,覆盖键盘、触屏、缩放与 reduced motion。
- 浏览器循环:把 Canvas、倒计时、合成层 Demo 加上暂停/恢复、资源清理、DPR 与可观测性能指标。
- 组件边界:重写插件模板、模块化和观察者模式,补初始化/销毁/异常行为测试。
- 框架与构建:分别复现 Vue/AngularJS/Webpack 原理,再做一份现代版本对照表;旧 AngularJS 只在维护情境中继续部署。
- 安全发布:把可分享 Demo 放到隔离 origin;依赖固定版本,记录许可证和来源,发布后进行移动端、键盘、网络失败和权限回归。
来源与现代官方文档
上游固定提交为 awesome-vault/fe-awesome-demos@db7f353ef5d5697985d61a510fbee075c5c6bca3。归档标题和主题用于定位历史内容;README 中部分目录外链指向旧账号下的 SourceSave,可能跳转或失效,只有确认过的来源才应作为补充材料。
- 固定版本 README
- MDN:iframe 与 sandbox
- MDN:Window.postMessage 安全通信
- MDN:requestAnimationFrame
- MDN:Canvas API
- AngularJS 官方下载与生命周期说明
- Vue 官方指南
- Webpack Concepts
动手路线
- 挑一个 CSS 或 Canvas 示例,重写为可触屏、可键盘访问的现代版本。
- 把一个旧插件拆成核心逻辑、DOM 适配和样式三层,并补测试。
- 对照旧 Webpack 配置与当前构建工具,理解当年的问题而非复制当年的配置。
使用边界
仓库中有旧技术栈,适合作为历史练习和原理材料,不代表现在的项目初始化方案。
原始入口
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。