Guide.md 8.4 KB

XJS 项目开发指南(Guide)

本仓库的目标是做一套可用于生产环境的 JS + CSS 框架,最终在业务项目中只需要引入:

  • xjs.js(单文件 JS)
  • xjs.css(单文件 CSS)

但在本仓库内,为了保持可维护性,开发源码仍然分散在多个文件中(例如 animal.jslayer.js),再通过构建脚本合并为单文件产物。

本文档用于统一后续完善/开发的目录约定、命名规范、编码习惯、测试方式、发布流程。请把它当成项目的“团队约定”。


1. 目录结构与职责边界

当前结构(关键文件):

  • animal.js:动画/选择器核心(Selection / animate / svg / timeline / scroll / inView 等能力)
  • layer.js:弹出层组件(UI + 交互逻辑)
  • xjs.css:库运行时需要的所有 UI 样式(例如 Layer 的 .layer-*
  • xjs.js
    • 开发阶段:加载器(按顺序加载 animal.js + layer.js
    • 同仓库内还可能包含“合并构建版本”的历史内容;开发时不要手改合并产物
  • dist/xjs.js:生产合并产物(由构建命令生成)
  • doc/index.html:统一测试/文档入口(支持点击导航直接进入示例页面)
  • main.go:构建与本地静态服务脚本

源码与产物的黄金规则

  • 只改源码animal.js / layer.js / xjs.css / doc/**
  • 不手改产物dist/xjs.js(以及任何由构建生成的合并文件)
  • 任何对外发布dist/xjs.js + xjs.css 为准

2. 本地开发 / 测试流程(推荐路径)

2.1 启动静态服务

仓库自带 Go 静态服务(默认端口 8080):

go run main.go serve

然后在浏览器打开:

  • http://localhost:8080/doc/index.html

说明:doc/index.html 会作为“测试总控台”,左侧导航/中间列表/右侧 iframe 组合用于快速打开各类测试页面。

2.2 构建生产单文件(合并)

animal.js + layer.js 合并输出到 dist/xjs.js

go run main.go build

或指定输出路径:

go run main.go build path/to/xjs.js

3. 对外 API / 全局变量规范

3.1 全局导出(必须稳定)

对外只承诺以下全局变量(避免污染):

  • window.xjs:主入口(推荐统一使用)
  • window.animal:兼容别名(与 xjs 等价)
  • window.Layer:Layer 构造/工厂入口

可选行为:

  • 不默认导出 $
  • 只有当业务方在引入前显式设置 window.XJS_GLOBAL_DOLLAR = true 时,才会在 $ 未被占用的前提下导出 $ = xjs

3.2 API 设计原则(统一风格)

  • 单入口:所有能力尽量从 xjs(selector) 返回的 Selection 链式对象进入
  • 强约束、少魔法:避免“隐式全局配置”;如需全局配置,集中在 xjs.config(未来可扩展)
  • 兼容性优先级:能用 WAAPI 就用 WAAPI;不支持时优雅降级(必要时 fallback 到 requestAnimationFrame)
  • 返回值规范
    • 异步行为返回 Promise(例如 animate().then(...)
    • 链式/操作型方法返回 Selection 以支持链式调用(例如 .layer(...).addClass(... ) 未来扩展)

4. JS 命名规范与编码约定

4.1 文件/模块命名

  • 文件名:全小写 + 下划线/无分隔(当前采用 animal.jslayer.js,新增模块保持一致)
  • 模块边界清晰
    • animal.js:核心选择器与动画体系(不直接引入 UI 样式)
    • layer.js:UI 组件(允许依赖 xjs.css

4.2 变量/函数命名

  • 函数camelCase
  • PascalCase
  • 常量UPPER_SNAKE_CASE
  • 私有/内部约定:以下划线前缀标识(例如 _fire_onKeydown

4.3 选择器与 Selection 约定

  • xjs(selector) 返回 Selection(继承 Array 的可链式集合)
  • Selection 实例方法命名尽量用动词:animate / draw / inViewAnimate / layer / unlayer
  • 新增能力优先做成 Selection 方法,而不是新增全局函数

4.4 参数命名与可扩展性

  • Options 对象:使用 plain object(JSON 友好)
  • 动画参数:把“动画属性”和“控制参数(duration/easing/loop 等)”分清
    • 不确定的配置键,不要让它误入“可动画属性”的判定
    • 建议将“非动画属性”的扩展项放进 params.options(现有实现已倾向此策略)

4.5 兼容性/健壮性

  • 代码应能在“没有 bundler”的脚本环境运行
  • 避免依赖现代语法到不可控程度(如确需使用,确保目标环境可用)
  • 对 DOM/Window 等对象引用前做存在性判断(SSR/非浏览器环境不会直接崩溃)

5. CSS 规范(xjs.css

5.1 单文件策略

  • 所有库运行时 UI 样式集中在 xjs.css
  • JS 侧不要注入大量 <style>(可接受“确保已引入 CSS”的兜底逻辑,但不把完整样式写入 JS)

5.2 命名空间与前缀(避免污染业务)

目前 Layer 使用 .layer-*,后续新增组件建议遵循:

  • 组件前缀x-<component>-* 或沿用当前 layer-*(但需保持一致)
  • 推荐做法:统一前缀策略(后续若决定全库统一 xjs-,则逐步迁移)

目标是:业务 CSS 不会因为类名冲突而被库“意外影响”,也不会轻易覆盖库样式。

5.3 主题化(建议方向)

新增 UI 组件时,尽量通过 CSS 变量暴露可定制项:

  • --xjs-color-primary
  • --xjs-radius-md
  • --xjs-shadow-lg
  • --layer-...(若继续沿用 layer 命名空间)

并保证:

  • 默认值可用
  • 业务覆盖变量即可换肤(不需要改库内部选择器)

6. 文档与测试(doc/

6.1 入口约定

  • 所有测试页面统一从 doc/index.html 进入
  • 新增测试页面时:
    • 放到合适的子目录(例如 doc/layer/doc/svg/doc/tween_*
    • doc/index.html 的导航树中挂入口,保证“可点击直达”

6.2 测试页面规范(建议)

  • 每个测试页只验证一类能力(避免“一页测所有导致回归困难”)
  • 页面顶部写清楚:
    • 测试目标
    • 预期现象
    • 参数组合/边界条件

7. 扩展开发指南(新增能力的推荐落点)

7.1 新增动画能力(优先落在 animal.js

典型落点:

  • 新增 Selection 方法:Selection.prototype.xxx = function (...) { ... }
  • 或在 Selection 类体内增加方法(更推荐,保持结构统一)
  • 如需新增静态能力:挂在 xjs.xxx = ...(需要同时考虑 animal 别名)

7.2 新增 UI 组件(独立文件 + CSS )

推荐方式:

  • 新增 component_xxx.js(或未来统一 components/xxx.js
  • xjs.css 增加 xxx-*(或 xjs-xxx-*)样式
  • 在构建阶段把该模块纳入单文件合并(更新 main.go build() 的拼接顺序)

当前 main.go 固定合并 animal.js + layer.js,当模块增长时建议升级为“配置式列表”。


8. 发布与回归清单(面向生产)

每次准备对外发布(或业务项目更新版本)前建议走一遍:

  • 功能回归
    • 打开 doc/index.html,对本次变更相关页面逐个验证
  • 构建产物
    • 执行 go run main.go build
    • 确认 dist/xjs.js 更新(不要手改)
  • 对外 API 稳定性
    • xjs/animal/Layer 是否都存在
    • $ 是否仍然是“显式开关才导出”
  • 样式影响面
    • xjs.css 的类名是否避免与业务冲突
    • 是否通过 CSS 变量提供可配置项(可选但推荐)

9. 建议的后续演进(非强制,但推荐)

当模块越来越多时,建议逐步引入以下工程化能力(仍保持“最终只发两个文件”的目标):

  • 源码目录化:例如 src/animal/src/layer/src/core/
  • 构建脚本升级main.go 从“硬编码拼接两个文件”升级为“按清单拼接多个文件”
  • 产物头信息:在 dist/xjs.js 注入版本号、构建时间、变更摘要(便于定位线上问题)
  • 最小化/压缩(可选):如需压缩,保持可回溯到未压缩构建(source map 视需求)

10. 约定优先级

如果本文档与源码现状出现不一致:

  1. 以本文档为准(作为未来统一标准)
  2. 在不破坏对外 API 的前提下,逐步把历史实现迁移到本文档规范