# 贡献指南
# 1. 目录结构
项目结构如下:
- docs # 文档地址
- plugin # [demo]工程用到的插件
- script # 脚本
- tests # 测试用例
- src
- common # [demo]公共内容
- packages # 对外发布的包内容
- pages # [demo]页面内容
- static # [demo]静态内容
- App.vue # [demo]应用入口
- main.js
- pages.json
组件库除了组件外,还有文档、示例、工程化配置等部分。为了维护起来方便,将示例、文档、组件都放在一个文件夹里,所以一个标准的组件目录如下:
- press-button
- press-button.vue # 组件
- README.md # 组件中文文档
- README.en-US.md # 组件英文文档
- demo.vue # 组件示例
src/packages 下就是由这些组件文件夹和一些公共文件构成。
上面的组织结构并不能直接用,还需要把 README.md 移动到 docs 中,把 demo.vue 移动到 src/pages 中。开发时会监听这些文件变动,发生变动后就把它们拷贝到需要的位置上。

根目录的
README.md与CONTRIBUTING.md是唯一数据源,docs/README.md与docs/contributing.md由npm run docs:sync自动生成,请勿直接编辑后者。
# 2. 开发
首先要执行如下命令,进行组件的派发:
npm run init
# 2.1. 组件开发
对于 H5、微信小程序、QQ 小程序有不同的启动命令:
# H5,建议 node 20 下运行
npm run dev
# 微信小程序,建议 node 16 下运行
npm run dev:mp-weixin
# QQ 小程序,建议 node 16 下运行
npm run dev:mp-qq
# 2.2. 新增组件
执行以下命令,然后交互式输入组件英文名、中文名等内容即可:
npm run new:comp
# 2.3. 文档开发
npm run docs:dev
# 2.4. 文档、示例部署
Press UI 接入了 CI,代码推送后会自动构建,并部署 H5、微信小程序、QQ 小程序三端示例及文档。
# 3. 发版
发版拆成三步,因为 npm 账号开启了 2FA(两步验证)后,npm publish 需要一次性验证码(OTP),而它在 standard-version 钩子里是以子进程执行的,无法交互式输入。
# Step 1:升版本号 + 生成 CHANGELOG + 生成产物 + 本地 commit 打 tag(不发布)
pnpm release:step1
# Step 2:手动带 OTP 发布到 npm,OTP 为验证器 App 里的 6 位动态码
pnpm release:step2 -- 123456
# Step 3:推送 commit 与 tag + 发送企业微信通知
pnpm release:step3
各步骤的产物与作用:
| 步骤 | 命令 | 作用 | 需要 OTP |
|---|---|---|---|
| Step 1 | pnpm release:step1 | 升版本号、生成 CHANGELOG.md、生成纯净产物到 log/press-ui/components、git commit 并打 tag | 否 |
| Step 2 | pnpm release:step2 -- <OTP> | 在产物目录执行 npm publish | 是 |
| Step 3 | pnpm release:step3 | git push 分支与 tag、发送版本通知 | 否 |
其他版本类型:
pnpm release:step1:minor # 次版本号,如 5.0.29 -> 5.1.0
pnpm release:step1:beta # 预发布版本,如 5.0.29 -> 5.0.30-beta.0
预发布版本在 Step 2 会自动带上 --tag beta,不会污染 latest。
# 3.1. 免 OTP 发布
若不想每次手动输入验证码,可在 npmjs 官网 (opens new window) 生成 Automation 类型的 Access Token(该类型可绕过 2FA),写入 ~/.npmrc:
//registry.npmjs.org/:_authToken=<your-automation-token>
此时 Step 2 无需传 OTP,一步到位的 pnpm release 也能正常工作。
# 3.2. 常见问题
报错 404 Not Found - PUT https://registry.npmjs.org/press-ui
不是包不存在,而是登录态失效。npm 对无发布权限的 PUT 请求会返回 404 而非 401,以避免泄露私有包是否存在。用 npm whoami 确认,若报 E401 则重新登录:
npm login # 项目根目录的 .npmrc 已把 registry 指向 npmjs,无需额外传参
npm whoami # 应输出你的用户名
注意:不要用
sudo执行发版命令。sudo会把HOME切到/var/root,导致读不到~/.npmrc里的登录凭证。
报错 EOTP This operation requires a one-time password
Step 2 没带 OTP,或验证码已过期(有效期约 30 秒)。重新看验证器再执行一次 Step 2 即可,无需重跑 Step 1。
# 4. 开发规范
# 4.1. 代码与提交
- 代码需符合公司代码规范,提交前请执行
npm run lint:fix与npm run lint:css:fix - 提交信息推荐 Angular 规范 (opens new window),因为
CHANGELOG.md由standard-version依据提交类型自动生成
# 4.2. 命名规范
- 对象、类、组件:大驼峰,首字母大写
- 变量、方法:小驼峰,首字母小写,如
loader、post、appBase、getAreaCode - 文件名:小写 + 中划线,如
message-dialog,不能用messageDialog - 类名:符合 BEM (opens new window) 规范,并以
press为前缀
# 4.3. 其他
对外 API 需简单、易记忆,比如 change、list,最好由一个单词组成,不能简写,与业界流行组件库对齐。
不能在组件内部 console.log。
# 5. 细节
# 5.1. rem单位
目前有的组件使用的单位是rem
- 优势:h5端适配更好,更合适
- 劣势:在小程序等其他端需要额外的插件来转换
Press UI并不强制单位,只要组件内部统一即可。
# 5.2. 准入条件
Press UI内的组件、逻辑需要有一定的通用性或复杂性,比如button、input、area、message-detail等组件通用型强,schedule-tree组件复杂度高。
宁缺毋滥,沉入的组件必须完成 BEM 改造,必须与业务充分解耦。
取乎其上,得乎其中,取乎其中,得乎其下,取乎其下,其无所得也。
一开始就尽量把组件设计好,坚持高标准,避免后面返工。
# 5.3. 脚本优先
js/ts比html灵活,能写在js/ts中的,就不要在组件中判断,灵活意味着通用性强,在跨平台、横竖屏、技术栈迁移时候,js/ts都能够很方便的复用,但是组件就不行。
# 5.4. 项目依赖关系
Press UI 底层依赖 t-comm、plugin-light 等库。
# 5.5. 适配多平台、多场景
Press UI 在兼容 Vue3 项目、非 uni-app 环境、APP 环境时,采用的实现方式为,新建工程,并将 Press UI 组件库作为子仓库。
# 5.6. 通用 & 灵活
下图是 H5、小程序、APP语法灵活度的对比。
Press UI 在编写跨端代码的时候,采用以下原则:
- 对齐短板,抹平差异,提供通用API
- 特殊场景下,条件编译,保持灵活性
这里举一些 H5 环境下渐进式增强的例子:
- 函数式调用组件的时候,可以动态创建 Dom,无需预埋组件
popover-plus点击空白处会收起,即clickOutSidelist支持自动检测外层scroller,即支持任意父级的滚动
# 5.7. i18n 实现
有几个核心函数:
setLang,设置语言,包括初次设置和切换语言。如果携带了额外的语言包,则会调用local.use或者local.add进行注入initDemoI18n,示例工程混入。包括onReady时,根据当前组件名称设置navigationBarTitle,以及提供t方法,t方法会优先从this.$options.i18n中取词汇表,否则调用locale/index中的t方法getLocale,获取当前语言。如果是iframe内,则从location.href中获取,否则从storage中获取toggleI18n,切换语言。会先通过storage注入新的语言标识。H5下会执行location.reload,非 H5 下,会调用setLang和uni.reLaunch
App.vue 中会执行 setLang,进行示例工程所有语言包的注入,并进行缓存。切换语言时,也会调用 setLang 无需传入语言包。