Skip to content

Commit 6829a2d

Browse files
committed
build: build lib update
1 parent 4ae12a7 commit 6829a2d

6 files changed

Lines changed: 180 additions & 11 deletions

File tree

NPM_README.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# @w.ui/wui-react
22

3-
基于 React 19 和 Ant Design 6 的高质量组件库,提供 300+ 可复用的业务组件。
3+
基于 React 19 和 Ant Design 6 的高质量组件库,提供 100+ 可复用的业务组件。
44

55
## ✨ 特性
66

@@ -46,6 +46,30 @@ const App = () => {
4646
export default App
4747
```
4848

49+
## 入口与按需导入(推荐理解)
50+
51+
本包同时支持两种导入方式:
52+
53+
- **主包单入口**`@w.ui/wui-react`(向后兼容,导出聚合)
54+
- **子路径多入口**`@w.ui/wui-react/core | /stateful | /stateless`(更细粒度 tree-shaking)
55+
56+
| 源入口(源码) | 使用方 import 路径 | 对应产物(发布后) |
57+
|---|---|---|
58+
| `src/lib/index.ts` | `@w.ui/wui-react` | `pro-react-components.es.js` / `pro-react-components.umd.js` / `index.d.ts` |
59+
| `src/lib/core.ts` | `@w.ui/wui-react/core` | `entries/core.es.js` / `entries/core.cjs.js` / `entries/core.d.ts` |
60+
| `src/lib/stateful.ts` | `@w.ui/wui-react/stateful` | `entries/stateful.es.js` / `entries/stateful.cjs.js` / `entries/stateful.d.ts` |
61+
| `src/lib/stateless.ts` | `@w.ui/wui-react/stateless` | `entries/stateless.es.js` / `entries/stateless.cjs.js` / `entries/stateless.d.ts` |
62+
|(样式)| `@w.ui/wui-react/style.css` | `style.css` |
63+
64+
### 子路径按需导入示例
65+
66+
```tsx
67+
import { KeepAlive } from '@w.ui/wui-react/core'
68+
import { TreeList } from '@w.ui/wui-react/stateful'
69+
import { SmartVideoPlayer } from '@w.ui/wui-react/stateless'
70+
import '@w.ui/wui-react/style.css'
71+
```
72+
4973
## 📚 组件列表
5074

5175
本库包含 100+ 组件,包括但不限于:
@@ -58,6 +82,30 @@ export default App
5882
- ResponsiveTable - 响应式表格
5983
- GlobalSearch - 全局搜索
6084

85+
### 有状态组件(stateful)
86+
87+
- CheckableTags - 可勾选标签组
88+
- MarkmapHooks - Markmap 思维导图 Hooks
89+
- MermaidHooks - Mermaid 渲染 Hooks
90+
- TreeList - 树形列表
91+
92+
### 无状态组件(stateless)
93+
94+
stateless 组件较多(动画/展示/输入/媒体等)。下面列出部分常用组件名(按导出名):
95+
96+
- AutoScrollSection
97+
- DescBox
98+
- RadioInput
99+
- CodeHighlighter
100+
- ReMarkdown
101+
- PDFExport
102+
- SmartVideoPlayer
103+
- FixMusicPlayer
104+
- Loading
105+
- OneTimePasscode
106+
107+
完整清单建议查看仓库:`src/lib/stateless.ts`(导出即组件清单),或访问 Storybook。
108+
61109
### UI 组件
62110

63111
- AdvancedCodeBlock - 高级代码块

docs/LIBRARY_PUBLISH_GUIDE.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
```json
5555
{
5656
"name": "@w.ui/wui-react",
57-
"version": "3.1.0",
57+
"version": "3.x.x",
5858
"files": ["dist-lib"],
5959
"main": "./dist-lib/pro-react-components.umd.js",
6060
"module": "./dist-lib/pro-react-components.es.js",
@@ -97,6 +97,18 @@
9797
}
9898
```
9999

100+
## 1.4 “入口 → exports → 产物文件”一对一对照表
101+
102+
> 你可以把它理解为:**写入口文件** → 通过 Vite 配置生成 **产物文件**`package.json#exports` 决定消费者 `import` 时具体会命中哪个文件。
103+
104+
| 源入口(源码) | 使用方 import 路径 | `exports`| 由哪个构建生成 | 对应产物文件(发布后实际存在) |
105+
|---|---|---|---|---|
106+
| `src/lib/index.ts` | `@w.ui/wui-react` | `.` | `npm run build:lib``vite.config.lib.ts`| `dist-lib/pro-react-components.es.js`(import)<br/>`dist-lib/pro-react-components.umd.js`(require)<br/>`dist-lib/index.d.ts`(types) |
107+
| `src/lib/core.ts` | `@w.ui/wui-react/core` | `./core` | `npm run build:lib:entries``vite.config.lib.entries.ts`| `dist-lib/entries/core.es.js`(import)<br/>`dist-lib/entries/core.cjs.js`(require)<br/>`dist-lib/entries/core.d.ts`(types) |
108+
| `src/lib/stateful.ts` | `@w.ui/wui-react/stateful` | `./stateful` | `npm run build:lib:entries``vite.config.lib.entries.ts`| `dist-lib/entries/stateful.es.js`(import)<br/>`dist-lib/entries/stateful.cjs.js`(require)<br/>`dist-lib/entries/stateful.d.ts`(types) |
109+
| `src/lib/stateless.ts` | `@w.ui/wui-react/stateless` | `./stateless` | `npm run build:lib:entries``vite.config.lib.entries.ts`| `dist-lib/entries/stateless.es.js`(import)<br/>`dist-lib/entries/stateless.cjs.js`(require)<br/>`dist-lib/entries/stateless.d.ts`(types) |
110+
|(无源码入口)| `@w.ui/wui-react/style.css` | `./style.css` | `npm run build:lib``vite.config.lib.ts`| `dist-lib/style.css` |
111+
100112
## 2. 开发规范
101113

102114
### 2.1 组件开发
@@ -211,14 +223,22 @@ npm run pub:beta
211223
212224
### 4.4 目前“发布到 npm 官网”到底走哪套逻辑?
213225

214-
发布脚本本质上调用的是 `npm publish`,npm 会在发布前自动执行 `prepublishOnly`
226+
发布推荐使用 `npm run pub`(脚本内部会执行 `npm publish dist-lib`)。
227+
228+
这样做的好处是:
229+
230+
- **发布包使用专用 README**`dist-lib/README.md`(由仓库根目录的 `NPM_README.md` 自动生成)
231+
- 不影响仓库根目录 `README.md`(它可以继续作为项目介绍)
232+
233+
发布前仍然会先执行构建:
215234

216235
当前 `prepublishOnly` 配置为:
217236

218237
- 先跑 `npm run build:lib`(生成主包单入口产物)
219238
- 再跑 `npm run build:lib:entries`(生成子路径多入口产物)
239+
- 最后跑 `npm run prepare:lib:publish`(生成 `dist-lib/package.json` + `dist-lib/README.md`,用于发布)
220240

221-
因此:**发布到 npm 时两套都会构建,并且都会一起被发布(因为 `files` 仅包含 `dist-lib`,而 `entries` 在其子目录下)**
241+
因此:**发布到 npm 时两套都会构建,并且都会一起被发布(发布目录为 `dist-lib/`,而 `entries` 在其子目录下)**
222242

223243
消费者具体用到哪套,取决于它的导入方式:
224244

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,13 @@
129129
"postbuild-storybook": "node ./scripts/add-storybook-base.js",
130130
"build:lib": "vite build -c vite.config.lib.ts",
131131
"build:lib:entries": "vite build -c vite.config.lib.entries.ts",
132+
"prepare:lib:publish": "node scripts/prepare-lib-publish.mjs",
132133
"build:lib:analyze": "cross-env USE_ANALYZE=1 vite build -c vite.config.lib.ts",
133134
"analyze:lib": "cross-env USE_ANALYZE=1 vite build -c vite.config.lib.ts",
134135
"check:components-index": "node scripts/validate-components-index.mjs",
135-
"prepublishOnly": "npm run build:lib && npm run build:lib:entries",
136-
"pub": "npm publish --access public",
137-
"pub:beta": "npm publish --tag beta --access public",
136+
"prepublishOnly": "npm run build:lib && npm run build:lib:entries && npm run prepare:lib:publish",
137+
"pub": "npm run prepublishOnly && npm publish dist-lib --access public",
138+
"pub:beta": "npm run prepublishOnly && npm publish dist-lib --tag beta --access public",
138139
"scanner": "npm run test && sonar-scanner -Dsonar.token=sqp_",
139140
"depcheck": "npx depcheck --json | grep -E 'dependencies|devDependencies|missing' || echo '依赖全干净!'",
140141
"clean": "npm prune && rimraf node_modules/.cache",

scripts/prepare-lib-publish.mjs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import fs from 'node:fs/promises'
2+
import path from 'node:path'
3+
4+
async function fileExists(filePath) {
5+
try {
6+
await fs.access(filePath)
7+
return true
8+
} catch {
9+
return false
10+
}
11+
}
12+
13+
function pickDefined(obj) {
14+
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined))
15+
}
16+
17+
async function main() {
18+
const repoRoot = process.cwd()
19+
const rootPkgPath = path.join(repoRoot, 'package.json')
20+
const distDir = path.join(repoRoot, 'dist-lib')
21+
22+
if (!(await fileExists(distDir))) {
23+
throw new Error('dist-lib 不存在:请先运行 npm run build:lib && npm run build:lib:entries')
24+
}
25+
26+
const rootPkg = JSON.parse(await fs.readFile(rootPkgPath, 'utf8'))
27+
28+
// dist-lib 作为“发布目录”时,exports/main/module/types 需要去掉 dist-lib 前缀。
29+
const distPkg = {
30+
name: rootPkg.name,
31+
version: rootPkg.version,
32+
description: rootPkg.description,
33+
keywords: rootPkg.keywords,
34+
homepage: rootPkg.homepage,
35+
bugs: rootPkg.bugs,
36+
license: rootPkg.license,
37+
author: rootPkg.author,
38+
contributors: rootPkg.contributors,
39+
repository: rootPkg.repository,
40+
sideEffects: rootPkg.sideEffects,
41+
peerDependencies: rootPkg.peerDependencies,
42+
main: './pro-react-components.umd.js',
43+
module: './pro-react-components.es.js',
44+
types: './index.d.ts',
45+
exports: {
46+
'.': {
47+
types: './index.d.ts',
48+
import: './pro-react-components.es.js',
49+
require: './pro-react-components.umd.js',
50+
},
51+
'./core': {
52+
types: './entries/core.d.ts',
53+
import: './entries/core.es.js',
54+
require: './entries/core.cjs.js',
55+
},
56+
'./stateful': {
57+
types: './entries/stateful.d.ts',
58+
import: './entries/stateful.es.js',
59+
require: './entries/stateful.cjs.js',
60+
},
61+
'./stateless': {
62+
types: './entries/stateless.d.ts',
63+
import: './entries/stateless.es.js',
64+
require: './entries/stateless.cjs.js',
65+
},
66+
'./style.css': './style.css',
67+
},
68+
}
69+
70+
const distPkgPath = path.join(distDir, 'package.json')
71+
await fs.writeFile(distPkgPath, JSON.stringify(pickDefined(distPkg), null, 2) + '\n', 'utf8')
72+
73+
// README:发布包使用 dist-lib/README.md(不影响仓库根 README.md)
74+
const npmReadmePath = path.join(repoRoot, 'NPM_README.md')
75+
const distReadmePath = path.join(distDir, 'README.md')
76+
if (await fileExists(npmReadmePath)) {
77+
await fs.copyFile(npmReadmePath, distReadmePath)
78+
} else {
79+
await fs.writeFile(
80+
distReadmePath,
81+
`# ${rootPkg.name}\n\nThis package is built from pro-react-admin.\n`,
82+
'utf8',
83+
)
84+
}
85+
86+
// LICENSE:npm 展示会优先识别包根目录的 LICENSE
87+
const licenseSrc = path.join(repoRoot, 'LICENSE')
88+
const licenseDest = path.join(distDir, 'LICENSE')
89+
if (await fileExists(licenseSrc)) {
90+
await fs.copyFile(licenseSrc, licenseDest)
91+
}
92+
93+
// 给发布目录一个最小 .npmignore(可选):不强制添加,避免误删产物。
94+
}
95+
96+
main().catch((err) => {
97+
// eslint-disable-next-line no-console
98+
console.error(err)
99+
process.exit(1)
100+
})

src/components/stateless/SmartVideoPlayer/svpI18n.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { createInstance } from 'i18next'
22
import { initReactI18next } from 'react-i18next'
33

4-
import zh from '@/locales/zh/translation'
5-
import en from '@/locales/en/translation'
4+
import zh from '@/locales/zh/translation.js'
5+
import en from '@/locales/en/translation.js'
66

77
export const SVP_UI_LANGUAGE_STORAGE_KEY = 'svpUiLanguage'
88

src/i18n/i18n.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import i18n from 'i18next'
22
import { initReactI18next } from 'react-i18next'
33
import LanguageDetector from 'i18next-browser-languagedetector'
4-
import translationInZh from '../locales/zh/translation'
5-
import translationInEn from '../locales/en/translation'
4+
import translationInZh from '../locales/zh/translation.js'
5+
import translationInEn from '../locales/en/translation.js'
66

77
i18n
88
.use(LanguageDetector)

0 commit comments

Comments
 (0)