@bams-app/work-cli 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +235 -0
- package/bin/work-cli.js +74 -0
- package/commands/add.js +143 -0
- package/commands/build.js +83 -0
- package/commands/create.js +195 -0
- package/commands/dev.js +95 -0
- package/commands/env.js +39 -0
- package/commands/pages-entry.js +37 -0
- package/commands/pages-from-components.js +37 -0
- package/commands/umd.js +172 -0
- package/commands/update.js +119 -0
- package/index.js +8 -0
- package/lib/utils.js +196 -0
- package/package.json +29 -0
- package/templates/project/.envs/.env.dev-demo +14 -0
- package/templates/project/.envs/README.md +45 -0
- package/templates/project/.proxy.js.example +11 -0
- package/templates/project/README.md +58 -0
- package/templates/project/gitignore.tpl +35 -0
- package/templates/project/package.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# @bams-app/work-cli
|
|
2
|
+
|
|
3
|
+
BAMS-Work 全局开发工具(类似 vue-cli 模式),提供**项目初始化**与**组件开发命令**。
|
|
4
|
+
|
|
5
|
+
## 设计思路
|
|
6
|
+
|
|
7
|
+
`work-cli` 是**薄壳**,不内嵌任何模板/服务/能力包代码,全部复用 work 仓库发布到 npm 的包:
|
|
8
|
+
|
|
9
|
+
| 能力 | 来源包 |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| 项目/组件创建 | `@bams-app/create-ui-component`、`@bams-app/create-ui-page`、`@bams-app/create-ui-base`(内部引用 `@bams-app/ui-*-template`) |
|
|
12
|
+
| 开发服务 / 构建 | `@bams-app/ui-dev-server`(serve / build-app / build-umd) |
|
|
13
|
+
| 环境变量加载 | `@bams-app/shared-env` |
|
|
14
|
+
| 环境配置创建 | `@bams-app/create-env`(交互式生成 `.envs/.env.dev-<alias>`) |
|
|
15
|
+
| 动态入口生成 | `@bams-app/create-pages-entry`(扫描 page-*/ui-* 生成 build-components-entry.js) |
|
|
16
|
+
| 批量页面创建 | `@bams-app/create-pages-from-components`(批量将 ui-* 转为 page-*,复用 create-ui-page) |
|
|
17
|
+
| 公共配置 | `@bams-app/configs`(app-config.json、可配置组件插槽默认值,被 ui-dev-server 与 store 依赖) |
|
|
18
|
+
|
|
19
|
+
- `create` 生成 **scope 目录模式** Monorepo:根 `workspaces: ["bams-components/*", "*-ui/*", "bams-ui"]`,
|
|
20
|
+
业务组件按 scope 目录存放(`energy-ui/ui-xxx`)。
|
|
21
|
+
- 项目根 `package.json` 只声明 `@bams-app/ui-dev-server` 与能力包,**不声明任何外部运行时依赖**;
|
|
22
|
+
项目模板 `.npmrc` 配置 `install-links=true`,`npm install` 时以复制方式安装 `file:` 链接的包
|
|
23
|
+
并解析其全部传递依赖(vue、ant-design-vue 等随能力包自动安装)。
|
|
24
|
+
- 能力包(`work/packages`、`work/ui`、`work/configs` 下的全部运行时包,含 ui 组件)声明
|
|
25
|
+
**以 ui-dev-server 的 dependencies 为单一来源**:本地验证模式逐个 `file:` 注入 work 本地
|
|
26
|
+
目录,发布后模式由 ui-dev-server 的 dependencies 随 npm 自动安装,业务组件与 runtime
|
|
27
|
+
共用同一份根 node_modules。
|
|
28
|
+
- 所有命令通过 `require.resolve()` 定位 work 包 bin 并以子进程委托执行,`WORK_PROJECT_ROOT` 环境变量注入项目根。
|
|
29
|
+
|
|
30
|
+
### 整体架构
|
|
31
|
+
|
|
32
|
+
```mermaid
|
|
33
|
+
flowchart LR
|
|
34
|
+
subgraph WORK["work 仓库(52 个可发布包)"]
|
|
35
|
+
A["能力包<br/>packages/ · ui/ · configs/"]
|
|
36
|
+
B["开发工具<br/>cli/(ui-dev-server · create-* · template)"]
|
|
37
|
+
end
|
|
38
|
+
subgraph REG["私有 registry<br/>npm.hedpy.cn"]
|
|
39
|
+
C["@bams-app/*"]
|
|
40
|
+
end
|
|
41
|
+
subgraph CLI["@bams-app/work-cli(薄壳)"]
|
|
42
|
+
D["create / add / dev / build / umd<br/>env / pages-entry / pages-from-components"]
|
|
43
|
+
end
|
|
44
|
+
subgraph PROJ["用户项目(Monorepo)"]
|
|
45
|
+
E["package.json<br/>仅声明 @bams-app/*"]
|
|
46
|
+
F["npm install<br/>install-links=true · 复制安装并解析传递依赖"]
|
|
47
|
+
end
|
|
48
|
+
A -->|"publish-all / 单包 npm publish"| C
|
|
49
|
+
B -->|"发布 + 依赖声明"| C
|
|
50
|
+
C -->|"registry 安装"| CLI
|
|
51
|
+
C -->|"发布后随 npm 自动安装"| PROJ
|
|
52
|
+
CLI -->|"create 以 file: 注入"| PROJ
|
|
53
|
+
CLI -->|"子进程委托 work 包 bin"| B
|
|
54
|
+
E --> F
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
用户项目(Monorepo,scope 目录模式)
|
|
59
|
+
├── package.json # workspaces: bams-components/*、*-ui/*、bams-ui
|
|
60
|
+
├── .bams-work/ # BAMS-Work 项目标记目录(勿删除)
|
|
61
|
+
├── .envs/.env.dev-<env> # 环境变量
|
|
62
|
+
├── .proxy.js # 自定义代理(可选)
|
|
63
|
+
├── bams-components/
|
|
64
|
+
│ └── ui-component-demo # 示例组件
|
|
65
|
+
└── energy-ui/ # 业务 scope 目录
|
|
66
|
+
└── ui-order-list
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 安装
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm i -g @bams-app/work-cli
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## 使用
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# 初始化 Monorepo 项目模版
|
|
79
|
+
bams-work create my-bams-project
|
|
80
|
+
cd my-bams-project
|
|
81
|
+
npm install
|
|
82
|
+
|
|
83
|
+
# 启动 work 开发环境(加载 .envs/.env.dev-<env>)
|
|
84
|
+
bams-work dev demo # 默认组件 ui-component-demo
|
|
85
|
+
bams-work dev demo ui-order-list # 指定组件
|
|
86
|
+
|
|
87
|
+
# 构建宿主应用(production,输出 dist/)
|
|
88
|
+
bams-work build ui-order-list
|
|
89
|
+
|
|
90
|
+
# 构建组件 UMD 产物(输出 dist/umd/)
|
|
91
|
+
bams-work umd ui-order-list
|
|
92
|
+
|
|
93
|
+
# 在 scope 目录下创建新组件
|
|
94
|
+
bams-work add --dir energy-ui --name ui-order-list
|
|
95
|
+
bams-work add --dir energy-ui --name page-order-list --type page
|
|
96
|
+
bams-work add --dir bams-components --name ui-base-btn --type base
|
|
97
|
+
|
|
98
|
+
# 升级 @bams-app 包(查询最新版并重装依赖)
|
|
99
|
+
bams-work update
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 命令一览
|
|
103
|
+
|
|
104
|
+
| 命令 | 说明 |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| `create <name>` | 初始化 Monorepo 项目模版(含示例组件与 `.bams-work/` 标记) |
|
|
107
|
+
| `add --dir <scope> --name <name>` | 在 scope 目录下创建组件(component/page/base),并注册 workspace |
|
|
108
|
+
| `dev <env> [component]` | 启动 work 开发环境(复用 ui-dev-server serve) |
|
|
109
|
+
| `build [component]` | 构建宿主应用(复用 build-app,production) |
|
|
110
|
+
| `umd [component]` | 构建组件 UMD 产物(复用 build-umd) |
|
|
111
|
+
| `env [--force]` | 交互式创建开发环境配置 `.envs/.env.dev-<alias>`(复用 create-env) |
|
|
112
|
+
| `update [--skip-install]` | 升级 `@bams-app` 包:查询最新版本、更新 ui-dev-server 声明并重装依赖 |
|
|
113
|
+
| `pages-entry --dir <dir> --type <page\|component>` | 扫描 page-*/ui-* 目录生成 webpack 动态入口(复用 create-pages-entry) |
|
|
114
|
+
| `pages-from-components --dir <dir>` | 批量将 ui-* 组件转为 page-* 页面(复用 create-pages-from-components) |
|
|
115
|
+
|
|
116
|
+
### 组件目录规范
|
|
117
|
+
|
|
118
|
+
业务组件(`<scope>/ui-xxx`)包含:`index.js`、`package.json`(`@<scope>/ui-xxx`)、
|
|
119
|
+
`src/`(`apis` / `business` / `constants` / `i18n` / `mock` / `theme` / `component.vue`)。
|
|
120
|
+
|
|
121
|
+
## 开发环境机制
|
|
122
|
+
|
|
123
|
+
- `.envs/.env.dev-<env>`:环境配置,`dev <env>` 时由 `@bams-app/shared-env` 加载。
|
|
124
|
+
- 代理:项目根 `.proxy.js`(参考 `.proxy.js.example`)。
|
|
125
|
+
- webpack 扩展:项目根 `vue.config.extend.js`(导出对象或 `({ env, projectRoot }) => 对象`)。
|
|
126
|
+
- 可配置插槽:`COMPONENT_*` 环境变量 + `@configurable/*` 别名(login / header / startr-layout)。
|
|
127
|
+
- 能力包可选组件(未安装时)由 `OPTIONAL_PACKAGE_FALLBACKS` 兜底 alias 到空入口,保证编译不报错。
|
|
128
|
+
|
|
129
|
+
## 发布流程
|
|
130
|
+
|
|
131
|
+
所有 work 包统一发布到 npm registry,**默认官方 npm(registry.npmjs.org)**,通过环境变量
|
|
132
|
+
`NPM_REGISTRY` 可随时切换到私有 registry(如 `https://npm.hedpy.cn/`)。work 下所有含
|
|
133
|
+
`package.json` 的目录(`packages/`、`cli/`、`ui/`、`configs/` 等)都会被打包发布,
|
|
134
|
+
`private` 包自动跳过:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# 0. 登录对应 registry(每次切换目标后需重新登录)
|
|
138
|
+
npm login --registry=https://registry.npmjs.org/ # 发布官方
|
|
139
|
+
npm login --registry=https://npm.hedpy.cn/ # 切到私服时
|
|
140
|
+
|
|
141
|
+
# 1. 在仓库根目录一键发布全部 work 包(交互式选择版本,只升不降)
|
|
142
|
+
yarn publish-all # 默认发布官方 npm
|
|
143
|
+
NPM_REGISTRY=https://npm.hedpy.cn/ yarn publish-all # 发布到私服
|
|
144
|
+
|
|
145
|
+
# 2. 发布 work-cli 本体(dependencies 改为 registry 版本号后)
|
|
146
|
+
cd work-cli && npm publish
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 单包发布
|
|
150
|
+
|
|
151
|
+
仅修改了某个包时,可跳过批量发布,直接在该包目录 `npm publish --registry=<目标>`(`private`
|
|
152
|
+
包无法发布,版本号已存在时需先手动修改该包 `package.json` 的 version):
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
cd work/packages/utils && npm publish --registry=https://registry.npmjs.org/
|
|
156
|
+
cd work/ui/ui-header-component && npm publish --registry=https://registry.npmjs.org/
|
|
157
|
+
cd work/cli/create-ui-component && npm publish --registry=https://registry.npmjs.org/
|
|
158
|
+
cd work/configs && npm publish --registry=https://registry.npmjs.org/
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
单包发布只影响该包,其他包版本号不变;需要整体提升版本时使用 `yarn publish-all`。
|
|
162
|
+
发布官方 npm 时 `@bams-app` scope 会随首个 scoped 包自动创建,无需预先注册。
|
|
163
|
+
|
|
164
|
+
能力包(`@bams-app/*`,含 `work/ui` 下的 ui 组件包)由 `ui-dev-server` 的 dependencies
|
|
165
|
+
统一声明,发布后随 `npm install` 自动安装到用户项目,无需逐包注入。
|
|
166
|
+
|
|
167
|
+
发布后 work-cli 的 `dependencies` 应从 `file:../work/cli/...` 改为对应 registry 版本号
|
|
168
|
+
(`^0.1.0` 等),`create` 生成的项目则声明 `"@bams-app/ui-dev-server": "^0.1.0"`。
|
|
169
|
+
|
|
170
|
+
## 用户项目升级
|
|
171
|
+
|
|
172
|
+
用户项目依赖 `@bams-app/*` 的方式决定升级方式:本地验证模式为 `file:` 引用 work 本地包,
|
|
173
|
+
发布后模式仅直接依赖 `@bams-app/ui-dev-server`(`^0.1.0`),能力包由 ui-dev-server 的
|
|
174
|
+
dependencies(`"*"`)传递安装。
|
|
175
|
+
|
|
176
|
+
### 一键升级(推荐)
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
bams-work update
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
自动完成:本地 file: 模式清除 node_modules 中的 file: 依赖缓存后重装,强制同步 work 最新
|
|
183
|
+
源码;发布后模式查询 registry 最新版本 → 更新 `package.json` 中 ui-dev-server 声明 →
|
|
184
|
+
重新 `npm install`(能力包 `*` 范围自动对齐最新)。`--skip-install` 可跳过重装。
|
|
185
|
+
|
|
186
|
+
### 本地验证模式(file:)
|
|
187
|
+
|
|
188
|
+
能力包以复制方式安装(`.npmrc` 的 `install-links=true`)。npm 对已安装的 file: 依赖会直接
|
|
189
|
+
跳过(即使源码已变化),`bams-work update` 会先清除 node_modules 中全部 file: 依赖缓存
|
|
190
|
+
再重装,强制重新复制 work 本地最新源码:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
bams-work update
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 发布后模式(registry)
|
|
197
|
+
|
|
198
|
+
| 场景 | 命令 |
|
|
199
|
+
| --- | --- |
|
|
200
|
+
| 常规升级(同大版本线 0.1.x) | `npm update @bams-app/ui-dev-server` |
|
|
201
|
+
| 跨大版本(0.1 → 0.2) | 改 package.json 为 `"@bams-app/ui-dev-server": "^0.2.0"` 后 `npm install` |
|
|
202
|
+
| 全部能力包强制最新 | `npm update`,或删除 node_modules 与 package-lock.json 后重装 |
|
|
203
|
+
|
|
204
|
+
`npm update <pkg>` 会把 ui-dev-server 升到其版本范围允许的最新版,并同步更新依赖树中的
|
|
205
|
+
能力包(`"*"` 范围 → 最新);跨大版本超出 `^` 约束,需手动修改版本号。
|
|
206
|
+
|
|
207
|
+
### 前提
|
|
208
|
+
|
|
209
|
+
- 升级前确保对应版本已发布:`"*"` 只解析 registry 上已发布的版本。
|
|
210
|
+
- registry 指向:项目 `.npmrc` 的 `@bams-app:registry` 决定从哪个源拉取 `@bams-app/*`;
|
|
211
|
+
发布到官方 npm 后需移除/注释该行(或改为官方源),否则升级拉取的仍是私服版本。
|
|
212
|
+
|
|
213
|
+
## 本地验证(未发布时)
|
|
214
|
+
|
|
215
|
+
未发布时通过 `file:` 引用本地 work 包完成端到端验证(`create` 会自动探测 work 仓库根,
|
|
216
|
+
将 ui-dev-server 与能力包以 `file:` 注入项目依赖,无需手动设置环境变量)。
|
|
217
|
+
注意:项目 `.npmrc` 的 `install-links=true` 使 `file:` 包以复制方式安装,
|
|
218
|
+
修改 work 包源码后需重新执行 `npm install` 才会生效:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
cd work-cli && npm install # 安装 file: 依赖(链接 work/cli 下的包)
|
|
222
|
+
npm link # 全局链接 bams-work
|
|
223
|
+
|
|
224
|
+
cd /tmp && rm -rf demo-app
|
|
225
|
+
bams-work create demo-app # 自动以 file: 引用本地 ui-dev-server 与能力包
|
|
226
|
+
cd demo-app && npm install
|
|
227
|
+
bams-work dev demo # 应返回 HTTP 200
|
|
228
|
+
bams-work build ui-component-demo
|
|
229
|
+
bams-work umd ui-component-demo
|
|
230
|
+
bams-work add --dir energy-ui --name ui-order-list
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## 环境要求
|
|
234
|
+
|
|
235
|
+
- Node.js >= 16.7.0
|
package/bin/work-cli.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const { colorize } = require('../lib/utils');
|
|
6
|
+
|
|
7
|
+
const pkg = require('../package.json');
|
|
8
|
+
|
|
9
|
+
const COMMANDS = {
|
|
10
|
+
create: '初始化 Monorepo 项目模版',
|
|
11
|
+
add: '在 scope 目录下创建组件(component/page/base)',
|
|
12
|
+
dev: '启动 work 开发环境(serve,复用 ui-dev-server)',
|
|
13
|
+
build: '构建宿主应用(production,复用 ui-dev-server)',
|
|
14
|
+
umd: '构建组件 UMD 产物(复用 build-umd)',
|
|
15
|
+
env: '创建开发环境配置(.envs/.env.dev-<alias>)',
|
|
16
|
+
update: '升级 @bams-app 包(更新 ui-dev-server 并重装依赖)',
|
|
17
|
+
'pages-entry': '扫描 page-*/ui-* 目录生成 webpack 动态入口',
|
|
18
|
+
'pages-from-components': '批量将 ui-* 组件转为 page-* 页面'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function printUsage() {
|
|
22
|
+
console.log('');
|
|
23
|
+
console.log(colorize('BAMS-Work CLI', 'cyan'), colorize(`v${pkg.version}`, 'gray'));
|
|
24
|
+
console.log(colorize('复用 work 已发布的包(ui-dev-server / shared-env / create-ui-*)', 'gray'));
|
|
25
|
+
console.log('');
|
|
26
|
+
console.log(colorize('用法:', 'bold'));
|
|
27
|
+
console.log(' bams-work <command> [options]');
|
|
28
|
+
console.log('');
|
|
29
|
+
console.log(colorize('命令:', 'bold'));
|
|
30
|
+
Object.entries(COMMANDS).forEach(([name, desc]) => {
|
|
31
|
+
console.log(` ${colorize(name.padEnd(20), 'green')} ${desc}`);
|
|
32
|
+
});
|
|
33
|
+
console.log('');
|
|
34
|
+
console.log(colorize('示例:', 'bold'));
|
|
35
|
+
console.log(' bams-work create my-bams-project # 初始化 Monorepo 项目');
|
|
36
|
+
console.log(' bams-work add --dir energy-ui --name ui-order-list');
|
|
37
|
+
console.log(' bams-work dev demo ui-component-demo # 启动 work 开发环境');
|
|
38
|
+
console.log(' bams-work build ui-component-demo # 构建宿主应用');
|
|
39
|
+
console.log(' bams-work umd ui-component-demo --out dist # 构建 UMD 产物');
|
|
40
|
+
console.log(' bams-work env demo # 创建开发环境配置');
|
|
41
|
+
console.log(' bams-work update # 升级 @bams-app 包');
|
|
42
|
+
console.log(' bams-work pages-entry --dir energy-ui --type page');
|
|
43
|
+
console.log(' bams-work pages-from-components --dir energy-ui');
|
|
44
|
+
console.log('');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function main() {
|
|
48
|
+
const [command, ...args] = process.argv.slice(2);
|
|
49
|
+
|
|
50
|
+
if (!command || command === '--help' || command === '-h' || command === 'help') {
|
|
51
|
+
printUsage();
|
|
52
|
+
process.exit(command ? 0 : 1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (command === '--version' || command === '-v' || command === 'version') {
|
|
56
|
+
console.log(pkg.version);
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const commandPath = path.resolve(__dirname, '../commands', `${command}.js`);
|
|
61
|
+
if (!fs.existsSync(commandPath)) {
|
|
62
|
+
console.error(colorize(`未知命令: ${command}`, 'red'));
|
|
63
|
+
printUsage();
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const handler = require(commandPath);
|
|
68
|
+
await handler(args);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
main().catch((err) => {
|
|
72
|
+
console.error(colorize('[work-cli] 错误:', 'red'), err.message || err);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
});
|
package/commands/add.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const { findProjectRoot, toKebabCase, error, success, info } = require('../lib/utils');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 用法: bams-work add --dir <scope> --name <name> [--type component|page|base]
|
|
8
|
+
* [--template <tpl>] [--use-component <name>] [--desc <text>]
|
|
9
|
+
*/
|
|
10
|
+
function parseArgs(args) {
|
|
11
|
+
const params = {};
|
|
12
|
+
for (let i = 0; i < args.length; i++) {
|
|
13
|
+
const arg = args[i];
|
|
14
|
+
if (!arg.startsWith('--')) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const key = arg.slice(2);
|
|
18
|
+
const next = args[i + 1];
|
|
19
|
+
if (next !== undefined && !next.startsWith('--')) {
|
|
20
|
+
params[key] = next;
|
|
21
|
+
i++;
|
|
22
|
+
} else {
|
|
23
|
+
params[key] = true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return params;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 将 scope 目录注册到项目根 workspaces(如 energy-ui → "energy-ui/*")
|
|
31
|
+
*/
|
|
32
|
+
function ensureWorkspaceScope(projectRoot, scopeDir) {
|
|
33
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
34
|
+
if (!fs.existsSync(pkgPath)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
38
|
+
const pattern = `${scopeDir}/*`;
|
|
39
|
+
const workspaces = Array.isArray(pkg.workspaces) ? pkg.workspaces : [];
|
|
40
|
+
if (!workspaces.includes(pattern)) {
|
|
41
|
+
workspaces.push(pattern);
|
|
42
|
+
pkg.workspaces = workspaces;
|
|
43
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
44
|
+
info(`已注册 workspace: ${pattern}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function resolveCreateBin(type) {
|
|
49
|
+
const pkgName = {
|
|
50
|
+
component: '@bams-app/create-ui-component',
|
|
51
|
+
page: '@bams-app/create-ui-page',
|
|
52
|
+
base: '@bams-app/create-ui-base'
|
|
53
|
+
}[type];
|
|
54
|
+
if (!pkgName) {
|
|
55
|
+
error(`不支持的组件类型: ${type}(可选 component / page / base)`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
return require.resolve(`${pkgName}/bin/${pkgName.split('/').pop()}.js`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function runCreateBin(createBin, binArgs) {
|
|
62
|
+
return new Promise((resolve) => {
|
|
63
|
+
const child = spawn(process.execPath, [createBin, ...binArgs], {
|
|
64
|
+
stdio: 'inherit'
|
|
65
|
+
});
|
|
66
|
+
child.on('error', (err) => {
|
|
67
|
+
error(`创建失败: ${err.message}`);
|
|
68
|
+
resolve(1);
|
|
69
|
+
});
|
|
70
|
+
child.on('exit', (code) => {
|
|
71
|
+
resolve(code ?? 1);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function main(args) {
|
|
77
|
+
const params = parseArgs(args);
|
|
78
|
+
|
|
79
|
+
if (!params.name) {
|
|
80
|
+
error('用法: bams-work add --dir <scope> --name <name> [--type component|page|base]');
|
|
81
|
+
error('示例: bams-work add --dir energy-ui --name ui-order-list');
|
|
82
|
+
error(' bams-work add --dir energy-ui --name page-order-list --type page');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!params.dir) {
|
|
87
|
+
error('请提供 --dir <scope>(组件所在 scope 目录名,如 energy-ui)');
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const projectRoot = findProjectRoot(process.cwd());
|
|
92
|
+
if (!projectRoot) {
|
|
93
|
+
error('未找到 BAMS-Work 项目(缺少 .bams-work 目录),请先执行 bams-work create <name>');
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const type = params.type || 'component';
|
|
98
|
+
const scopeDir = path.basename(path.resolve(params.dir));
|
|
99
|
+
if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(scopeDir)) {
|
|
100
|
+
error(`scope 目录名不合法: ${scopeDir}(必须使用小写字母、数字和中横线,如 energy-ui)`);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 将 scope 目录注册到项目 workspaces
|
|
105
|
+
ensureWorkspaceScope(projectRoot, scopeDir);
|
|
106
|
+
|
|
107
|
+
// 委托对应 create-ui-* 包(复用 work 的模板与命令)
|
|
108
|
+
const createBin = resolveCreateBin(type);
|
|
109
|
+
|
|
110
|
+
const binArgs = [
|
|
111
|
+
'--dir', path.resolve(projectRoot, scopeDir),
|
|
112
|
+
'--name', toKebabCase(params.name)
|
|
113
|
+
];
|
|
114
|
+
if (params.template) {
|
|
115
|
+
binArgs.push('--template', params.template);
|
|
116
|
+
}
|
|
117
|
+
if (params['use-component']) {
|
|
118
|
+
binArgs.push('--use-component', params['use-component']);
|
|
119
|
+
}
|
|
120
|
+
if (params.desc) {
|
|
121
|
+
binArgs.push('--desc', params.desc);
|
|
122
|
+
}
|
|
123
|
+
binArgs.push('--no-install');
|
|
124
|
+
|
|
125
|
+
const code = await runCreateBin(createBin, binArgs);
|
|
126
|
+
if (code !== 0) {
|
|
127
|
+
error('组件创建失败');
|
|
128
|
+
process.exit(code);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
success(`组件创建成功: ${toKebabCase(params.name)}(scope: ${scopeDir})`);
|
|
132
|
+
info(`开发: bams-work dev <env> ${toKebabCase(params.name)}`);
|
|
133
|
+
info(`UMD: bams-work umd ${toKebabCase(params.name)}`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
module.exports = main;
|
|
137
|
+
|
|
138
|
+
if (require.main === module) {
|
|
139
|
+
main(process.argv.slice(2)).catch((err) => {
|
|
140
|
+
error(err.message || err);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { findProjectRoot, error, info, run } = require('../lib/utils');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 用法: bams-work build [component] [-- <vue-cli args>]
|
|
7
|
+
* 委托 @bams-app/ui-dev-server/bin/build-app.js 构建宿主应用(production)
|
|
8
|
+
*/
|
|
9
|
+
async function main(args) {
|
|
10
|
+
const projectRoot = findProjectRoot(process.cwd());
|
|
11
|
+
if (!projectRoot) {
|
|
12
|
+
error('未找到 BAMS-Work 项目(缺少 .bams-work 目录),请先执行 bams-work create <name>');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let component = '';
|
|
17
|
+
let serviceArgs = [];
|
|
18
|
+
let i = 0;
|
|
19
|
+
|
|
20
|
+
while (i < args.length) {
|
|
21
|
+
const arg = args[i];
|
|
22
|
+
if (arg === '--') {
|
|
23
|
+
serviceArgs = args.slice(i + 1);
|
|
24
|
+
break;
|
|
25
|
+
} else if (arg === '--component' || arg === '-c') {
|
|
26
|
+
component = args[i + 1];
|
|
27
|
+
i += 2;
|
|
28
|
+
} else if (arg.startsWith('--')) {
|
|
29
|
+
serviceArgs = args.slice(i);
|
|
30
|
+
break;
|
|
31
|
+
} else if (!component) {
|
|
32
|
+
component = arg;
|
|
33
|
+
} else {
|
|
34
|
+
serviceArgs = args.slice(i);
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
i++;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let buildAppBin;
|
|
41
|
+
let sharedEnvBin;
|
|
42
|
+
try {
|
|
43
|
+
buildAppBin = require.resolve('@bams-app/ui-dev-server/bin/build-app.js');
|
|
44
|
+
sharedEnvBin = require.resolve('@bams-app/shared-env/bin/shared-env.js');
|
|
45
|
+
} catch (err) {
|
|
46
|
+
error('未安装 work 依赖包,请先在 work-cli 目录执行 npm install');
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
info(`构建宿主应用,组件: ${component || 'ui-component-demo'}`);
|
|
51
|
+
info(`工作目录: ${projectRoot}`);
|
|
52
|
+
|
|
53
|
+
const uiArgs = [buildAppBin];
|
|
54
|
+
if (component) {
|
|
55
|
+
uiArgs.push('-c', component);
|
|
56
|
+
}
|
|
57
|
+
uiArgs.push(...serviceArgs);
|
|
58
|
+
|
|
59
|
+
const env = { ...process.env, WORK_PROJECT_ROOT: projectRoot };
|
|
60
|
+
|
|
61
|
+
// 存在 .env.production 时通过 shared-env 加载,否则直接构建
|
|
62
|
+
const prodEnvFile = '.envs/.env.production';
|
|
63
|
+
let code;
|
|
64
|
+
if (fs.existsSync(path.join(projectRoot, prodEnvFile))) {
|
|
65
|
+
code = await run(
|
|
66
|
+
process.execPath,
|
|
67
|
+
[sharedEnvBin, '--project', '.', '--env', prodEnvFile, '--', ...uiArgs],
|
|
68
|
+
{ cwd: projectRoot, env }
|
|
69
|
+
);
|
|
70
|
+
} else {
|
|
71
|
+
code = await run(process.execPath, uiArgs, { cwd: projectRoot, env });
|
|
72
|
+
}
|
|
73
|
+
process.exit(code);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = main;
|
|
77
|
+
|
|
78
|
+
if (require.main === module) {
|
|
79
|
+
main(process.argv.slice(2)).catch((err) => {
|
|
80
|
+
error(err.message || err);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
});
|
|
83
|
+
}
|