@bams-app/work-cli 0.1.6 → 0.1.7

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 CHANGED
@@ -1,7 +1,8 @@
1
1
  # @bams-app/work-cli
2
2
 
3
- BAMS-Work 全局脚手架工具(类似 vue-cli 模式),提供**项目初始化**、**组件创建**与**环境配置**能力。
4
- 开发调试由用户项目**本地的** `@bams-app/ui-dev-server` 承担(`npm run dev:ui <环境标识>`),全局 CLI 不参与启动开发服务。
3
+ BAMS-Work 全局脚手架工具(类似 vue-cli 模式),提供**项目初始化**、**组件创建**、**环境配置**与**宿主应用打包**能力。
4
+ 开发调试由用户项目**本地的** `@bams-app/ui-dev-server` 承担(`npm run dev:ui <环境标识>`),全局 CLI 不参与启动开发服务;
5
+ 打包(`work build <app>`)直接调用应用的 `vue-cli-service`,**不经过 ui-dev-server**(它只负责开发服务)。
5
6
 
6
7
  ## 设计思路
7
8
 
@@ -12,11 +13,13 @@ BAMS-Work 全局脚手架工具(类似 vue-cli 模式),提供**项目初
12
13
  | ------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
13
14
  | 项目/组件创建 | `@bams-app/create-ui-component`、`@bams-app/create-ui-page`、`@bams-app/create-ui-base`(模板内置于各包 `templates/`) |
14
15
  | 开发服务 | `@bams-app/ui-dev-server`(由模板写入用户项目 `devDependencies`,`npm run dev:ui <环境标识>` 本地启动;环境标识由第 1 个位置参数传入) |
15
- | 环境变量加载 | `@bams-app/shared-env`(同上;其 `lib/env-loader` ui-dev-server 复用于解析环境标识) |
16
+ | 宿主应用 | `@bams-app/bams-app`、`@bams-app/project-startr`、`@bams-app/touch-startr`(随版本发布,`work create` 模板写入用户项目 `dependencies`) |
17
+ | 打包构建执行 | `@vue/cli-service`(由应用自身 `vue.config.js` 驱动,**不经过 ui-dev-server**;应用基础配置复用 `@bams-app/configs/vue.config.app-base`) |
18
+ | 环境变量加载 | `@bams-app/shared-env`(开发与打包同源:ui-dev-server 解析环境标识、`work build` 直接复用其 `lib/env-loader`) |
16
19
  | 环境配置创建 | `@bams-app/create-env`(交互式生成 `.envs/.env.dev-<alias>`) |
17
20
  | 动态入口生成 | `@bams-app/create-pages-entry`(扫描 page-_/ui-_ 生成 build-components-entry.js) |
18
21
  | 批量页面创建 | `@bams-app/create-pages-from-components`(批量将 ui-_ 转为 page-_,复用 create-ui-page) |
19
- | 公共配置 | `@bams-app/configs`(app-config.json、可配置组件插槽默认值,被 ui-dev-server store 依赖) |
22
+ | 公共配置 | `@bams-app/configs`(app-config.json、可配置组件插槽默认值、宿主应用 vue-cli 基础配置 `vue.config.app-base`、组件别名解析,被 ui-dev-server / store / 宿主应用依赖) |
20
23
 
21
24
  - `create` 生成 **scope 目录模式**项目:业务组件按 scope 目录存放(`energy-ui/ui-xxx`);
22
25
  项目根 `package.json` 声明 `demo-ui/*`、`bams-components/*`、`*-ui/*`、`apex-web/*`、`bams-ui`
@@ -27,8 +30,13 @@ BAMS-Work 全局脚手架工具(类似 vue-cli 模式),提供**项目初
27
30
  ui-dev-server 的 `dependencies` 维护**一处**,安装后提升到项目根 `node_modules`,
28
31
  webpack 的 `resolve.modules` 即指向该处,版本随 ui-dev-server 走。
29
32
  `create` **不生成**项目 `.npmrc`(`@bams-app/*` 默认走官方 npm)。
33
+ - 宿主应用(`@bams-app/bams-app`、`@bams-app/project-startr`、`@bams-app/touch-startr`)
34
+ 作为**可发布包**写入项目 `dependencies`,供 `work build` 打包;应用也可由项目内 `apps/<app>`
35
+ 提供(优先),二者取其一即可。
30
36
  - 开发调试**不经过 CLI**:`npm run dev:ui <环境标识> [组件名]` 即项目本地的 `ui-dev-server`
31
37
  (npm 走 `node_modules/.bin`),环境文件由其自行加载,追加的位置参数覆盖默认值。
38
+ - 打包**由 CLI 承担**:`work build <app>` 定位应用目录后,以该目录为 `cwd` 直接调用其
39
+ `vue-cli-service build`,并把 `WORK_PROJECT_ROOT` 指向项目根;**不经过 ui-dev-server**。
32
40
  - 其余命令通过 `require.resolve()` 定位 work 包 bin 并以子进程委托执行,`WORK_PROJECT_ROOT` 环境变量注入项目根。
33
41
 
34
42
  ### 整体架构
@@ -43,28 +51,35 @@ flowchart LR
43
51
  C["@bams-app/*"]
44
52
  end
45
53
  subgraph CLI["@bams-app/work-cli(全局 CLI)"]
46
- D["create / add / env<br/>pages-entry / pages-from-components"]
54
+ D["create / add / env<br/>pages-entry / pages-from-components<br/>build(打包宿主应用)"]
47
55
  end
48
56
  subgraph PROJ["用户项目"]
49
- E["package.json<br/>devDependencies:仅 ui-dev-server"]
57
+ E["package.json<br/>dependencies:宿主应用<br/>devDependencies:仅 ui-dev-server"]
50
58
  F["npm install<br/>依赖自动安装"]
51
59
  G["npm run dev:ui 环境标识<br/>本地 ui-dev-server"]
60
+ H["work build &lt;app&gt;<br/>应用自身 vue-cli-service"]
52
61
  end
53
62
  A -->|"publish-all / 单包 npm publish"| C
54
63
  B -->|"发布 + 依赖声明"| C
55
64
  C -->|"registry 安装"| CLI
56
- C -->|"registry 安装(ui-dev-server + 能力包 + 运行时依赖)"| PROJ
65
+ C -->|"registry 安装(ui-dev-server + 能力包 + 运行时依赖 + 宿主应用)"| PROJ
57
66
  CLI -->|"子进程委托 work 包 bin"| B
67
+ CLI -->|"直接调用应用 vue-cli-service(不走 ui-dev-server)"| H
58
68
  E --> F
59
69
  F --> G
70
+ F --> H
60
71
  ```
61
72
 
62
73
  ```
63
74
  用户项目(scope 目录模式)
64
- ├── package.json # 项目根配置
75
+ ├── package.json # 项目根配置(dependencies 宿主应用 + devDependencies ui-dev-server)
65
76
  ├── .bams-work/ # BAMS-Work 项目标记目录(勿删除)
66
- ├── .envs/.env.dev-<env> # 环境变量
77
+ ├── .envs/.env.dev-<env> # 开发环境变量
78
+ ├── .envs/.env.production # 打包环境变量(work build 默认加载)
67
79
  ├── .proxy.js # 自定义代理(可选)
80
+ ├── apps/ # 项目内宿主应用(可选,优先于依赖包)
81
+ │ └── <app>/
82
+ ├── dist/ # work build 产物目录
68
83
  ├── demo-ui/ # 默认组件 scope
69
84
  │ └── ui-component-demo # 示例组件
70
85
  └── energy-ui/ # 业务 scope 目录
@@ -93,6 +108,12 @@ npm run dev:ui demo ui-order-list # 指定组件(`-c ui-order-list` 等
93
108
  work add --dir energy-ui --name ui-order-list
94
109
  work add --dir energy-ui --name page-order-list --type page
95
110
  work add --dir demo-ui --name ui-base-btn --type base
111
+
112
+ # 打包宿主应用(不走 ui-dev-server,直接调用应用的 vue-cli-service)
113
+ work build bams-app # 默认加载 .envs/.env.production
114
+ work build project-startr --env prod # 指定环境文件(.envs/.env.dev-prod)
115
+ work build touch-startr -- --modern # `--` 之后透传给 vue-cli-service
116
+ npm run build:bams-app # 模板内置的等价脚本
96
117
  ```
97
118
 
98
119
  ### 命令一览
@@ -101,6 +122,7 @@ work add --dir demo-ui --name ui-base-btn --type base
101
122
  | -------------------------------------------------- | --------------------------------------------------------------------- |
102
123
  | `create <name>` | 初始化项目模版(含示例组件与 `.bams-work/` 标记) |
103
124
  | `add --dir <scope> --name <name>` | 在 scope 目录下创建组件(component/page/base),并注册 scope 目录 |
125
+ | `build <app> [--env <标识\|文件>] [-- <参数>]` | 打包宿主应用(`apps/<app>` 优先,回退依赖包;不走 ui-dev-server) |
104
126
  | `env` | 交互式创建开发环境配置 `.envs/.env.dev-<alias>`(复用 create-env) |
105
127
  | `pages-entry --dir <dir> --type <page\|component>` | 扫描 page-_/ui-_ 目录生成 webpack 动态入口(复用 create-pages-entry) |
106
128
  | `pages-from-components --dir <dir>` | 批量将 ui-_ 组件转为 page-_ 页面(复用 create-pages-from-components) |
@@ -145,12 +167,39 @@ work skills sync --force # 内容一致时也重新复制
145
167
  - 可配置插槽:`COMPONENT_*` 环境变量 + `@configurable/*` 别名(login / header / startr-layout)。
146
168
  - 能力包可选组件(未安装时)由 `OPTIONAL_PACKAGE_FALLBACKS` 兜底 alias 到空入口,保证编译不报错。
147
169
 
170
+ ## 打包宿主应用
171
+
172
+ `work build <app>` 用于把宿主应用打成静态产物,**全程不经过 `@bams-app/ui-dev-server`**
173
+ (它只是开发服务):
174
+
175
+ - **应用定位**:优先项目内 `apps/<app>`,回退到依赖包 `node_modules/@bams-app/<app>`
176
+ (须含 `package.json` 与 `vue.config.js`)。未传 `<app>` 且项目内仅一个可用应用时自动选中,
177
+ 否则列出可用应用并退出。
178
+ - **构建执行**:以**应用目录为 `cwd`** 直接调用该应用自身的 `@vue/cli-service build`,
179
+ 并注入 `WORK_PROJECT_ROOT=<项目根>`、`NODE_ENV=production`。应用基础配置
180
+ (externals、`@components-entry`、`@configurable/*` 别名、代理兜底)由
181
+ `@bams-app/configs/vue.config.app-base` 提供,仓库根与各应用共用同一份,避免漂移。
182
+ - **环境加载**:复用 `@bams-app/shared-env` 的 `lib/env-loader`,与开发服务同源。
183
+ 默认加载 `.envs/.env.production`;`--env <标识>` 解析为 `.envs/.env.dev-<标识>`
184
+ (`--env production` 即 `.env.production`);`--env <路径>` 直接按路径解析。
185
+ 应用私有 `.env.<mode>` 中同名变量覆盖项目根同名文件。
186
+ - **参数透传**:`--` 之后的参数原样传给 `vue-cli-service build`(如 `-- --modern`)。
187
+ - **产物目录**:由应用 `vue.config.js` 的 `outputDir` 决定(指向项目根 `dist`)。
188
+
189
+ ```bash
190
+ work build bams-app # 打包 bams-app(默认 production 环境)
191
+ work build project-startr --env dev # 加载 .envs/.env.dev-dev
192
+ work build touch-startr -e .envs/.env.dev-demo
193
+ work build bams-app -- --no-clean # 透传 vue-cli 参数
194
+ ```
195
+
148
196
  ## 发布流程
149
197
 
150
198
  所有 work 包统一发布到 npm registry,**默认官方 npm(registry.npmjs.org)**,通过环境变量
151
199
  `NPM_REGISTRY` 可随时切换到私有 registry(如 `https://npm.hedpy.cn/`)。work 下所有含
152
- `package.json` 的目录(`packages/`、`ui/`、`tooling/`、`cli/`、`configs/` 等)
153
- 都会被打包发布,`private` 包自动跳过:
200
+ `package.json` 的目录(`packages/`、`ui/`、`tooling/`、`cli/`、`configs/`、`apps/` 等)
201
+ 都会被打包发布,`private` 包自动跳过。宿主应用(`work/apps/*`)已去掉 `private` 并声明 `files`
202
+ 白名单,随版本作为 `@bams-app/<app>` 发布,供用户项目安装后由 `work build` 打包:
154
203
 
155
204
  ```bash
156
205
  # 0. 登录对应 registry(每次切换目标后需重新登录)
@@ -173,6 +222,7 @@ cd work/packages/utils && npm publish --registry=https://registry.npmjs.org/
173
222
  cd work/ui/ui-header-component && npm publish --registry=https://registry.npmjs.org/
174
223
  cd work/tooling/create-ui-component && npm publish --registry=https://registry.npmjs.org/
175
224
  cd work/configs && npm publish --registry=https://registry.npmjs.org/
225
+ cd work/apps/bams-app && npm publish --registry=https://registry.npmjs.org/
176
226
  ```
177
227
 
178
228
  单包发布只影响该包,其他包版本号不变;需要整体提升版本时使用 `yarn publish-all`。
@@ -184,8 +234,9 @@ cd work/configs && npm publish --registry=https://registry.npmjs.org/
184
234
 
185
235
  ## 用户项目升级
186
236
 
187
- 用户项目只声明 `@bams-app/ui-dev-server` 一个依赖,能力包与运行时依赖全部作为它的传递依赖解析到
188
- 同一份包,提升到项目根 `node_modules`。
237
+ 用户项目在 `devDependencies` 只声明 `@bams-app/ui-dev-server` 一个依赖,能力包与运行时依赖全部作为它的
238
+ 传递依赖解析到同一份包,提升到项目根 `node_modules`;`dependencies` 另声明宿主应用
239
+ (`@bams-app/bams-app` / `project-startr` / `touch-startr`,以 `"*"` 跟随 registry 最新已发布版本)。
189
240
 
190
241
  ui-dev-server 对能力包声明的是显式版本范围(`^x.y.z`),范围随 ui-dev-server 每次发布同步更新,
191
242
  因此升级就是一条命令:
@@ -194,6 +245,12 @@ ui-dev-server 对能力包声明的是显式版本范围(`^x.y.z`),范围
194
245
  npm i @bams-app/ui-dev-server@latest
195
246
  ```
196
247
 
248
+ 宿主应用随 `yarn publish-all` 同批次发布,升级时可一并刷新:
249
+
250
+ ```bash
251
+ npm i @bams-app/bams-app@latest @bams-app/project-startr@latest @bams-app/touch-startr@latest
252
+ ```
253
+
197
254
  新版本的依赖范围与 `package-lock.json` 中钉住的旧版本不再匹配,npm 会自动重新解析整套能力包,
198
255
  无需手工清理 lockfile(历史版本遗留的 `*` 范围才需要旧办法,见 git 历史)。
199
256
 
package/bin/work-cli.js CHANGED
@@ -10,6 +10,7 @@ const COMMANDS = {
10
10
  create: '初始化项目模版',
11
11
  add: '在 scope 目录下创建组件(component/page/base)',
12
12
  env: '创建开发环境配置(.envs/.env.dev-<alias>)',
13
+ build: '打包宿主应用(apps/<app> 或依赖中的 @bams-app/<app>,不走 ui-dev-server)',
13
14
  'pages-entry': '扫描 page-*/ui-* 目录生成 webpack 动态入口',
14
15
  'pages-from-components': '批量将 ui-* 组件转为 page-* 页面',
15
16
  skills: '把组件包内嵌的 SKILL.md 同步到项目根 .skills/(中立目录,与 AI 工具无关)'
@@ -17,7 +18,7 @@ const COMMANDS = {
17
18
 
18
19
  // 暂时下线的命令:commands/ 下的实现文件保留,恢复时删除此处对应项即可
19
20
  // dev:开发环境由用户项目本地的 ui-dev-server 启动(npm run dev:ui),CLI 不再承担
20
- const DISABLED_COMMANDS = ['dev', 'build', 'umd'];
21
+ const DISABLED_COMMANDS = ['dev', 'umd'];
21
22
 
22
23
  function printUsage() {
23
24
  console.log('');
@@ -36,6 +37,7 @@ function printUsage() {
36
37
  console.log(' work create my-bams-project # 初始化项目');
37
38
  console.log(' work add --dir energy-ui --name ui-order-list');
38
39
  console.log(' work env # 创建开发环境配置(交互式)');
40
+ console.log(' work build bams-app # 打包宿主应用(.envs/.env.production)');
39
41
  console.log(' work pages-entry --dir energy-ui --type page');
40
42
  console.log(' work pages-from-components --dir energy-ui');
41
43
  console.log(' work skills sync # 把组件包内嵌技能同步到 .skills/');
@@ -43,6 +45,10 @@ function printUsage() {
43
45
  console.log(colorize('开发调试:', 'bold'));
44
46
  console.log(' 在项目根目录执行 npm run dev:ui <环境标识>(由项目本地 ui-dev-server 启动并加载 .envs/ 环境文件)');
45
47
  console.log('');
48
+ console.log(colorize('打包:', 'bold'));
49
+ console.log(' work build <app> [--env <标识|文件>] [-- <vue-cli 参数>]');
50
+ console.log(' 直接以应用的 vue-cli-service 打包(默认 .envs/.env.production),不经过 ui-dev-server');
51
+ console.log('');
46
52
  }
47
53
 
48
54
  async function main() {
package/commands/build.js CHANGED
@@ -1,19 +1,121 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
- const { findProjectRoot, error, info, run } = require('../lib/utils');
3
+ const { findProjectRoot, error, info, warn, log, run, isDirectory } = require('../lib/utils');
4
4
 
5
5
  /**
6
- * 用法: work build [component] [-- <vue-cli args>]
7
- * 委托 @bams-app/ui-dev-server/bin/build-app.js 构建宿主应用(production)
6
+ * 用法: work build [app] [--env <alias|file>] [-- <vue-cli args>]
7
+ *
8
+ * 直接以应用的 vue-cli-service 打包宿主应用(默认 production),
9
+ * 不经过 @bams-app/ui-dev-server(它只负责开发服务)。
10
+ * 应用来源:优先项目内 apps/<app>,回退到依赖 node_modules/@bams-app/<app>。
11
+ * 环境变量复用 @bams-app/shared-env 的 env-loader(含应用私有 .env.<mode> 覆盖)。
8
12
  */
9
- async function main(args) {
10
- const projectRoot = findProjectRoot(process.cwd());
11
- if (!projectRoot) {
12
- error('未找到 BAMS-Work 项目(缺少 .bams-work 目录),请先执行 work create <name>');
13
- process.exit(1);
13
+
14
+ /** 判定目录是否为可打包的 vue-cli 应用(含 package.json 与 vue.config.js) */
15
+ function isAppDir(dir) {
16
+ return isDirectory(dir)
17
+ && fs.existsSync(path.join(dir, 'package.json'))
18
+ && fs.existsSync(path.join(dir, 'vue.config.js'));
19
+ }
20
+
21
+ /** @bams-app/foo -> foo;foo -> foo */
22
+ function toShortName(name) {
23
+ return name.startsWith('@') ? (name.split('/')[1] || name) : name;
24
+ }
25
+
26
+ /** 收集项目中可打包的应用(项目内 apps/ 与 node_modules/@bams-app/) */
27
+ function listAvailableApps(projectRoot) {
28
+ const apps = [];
29
+ const seen = new Set();
30
+
31
+ const addApp = (name, dir) => {
32
+ if (seen.has(name) || !isAppDir(dir)) {
33
+ return;
34
+ }
35
+ seen.add(name);
36
+ apps.push({ name, dir });
37
+ };
38
+
39
+ const internalDir = path.join(projectRoot, 'apps');
40
+ if (isDirectory(internalDir)) {
41
+ for (const entry of fs.readdirSync(internalDir, { withFileTypes: true })) {
42
+ if (entry.name.startsWith('.')) {
43
+ continue;
44
+ }
45
+ addApp(entry.name, path.join(internalDir, entry.name));
46
+ }
14
47
  }
15
48
 
16
- let component = '';
49
+ const scopeDir = path.join(projectRoot, 'node_modules', '@bams-app');
50
+ if (isDirectory(scopeDir)) {
51
+ for (const entry of fs.readdirSync(scopeDir, { withFileTypes: true })) {
52
+ if (entry.name.startsWith('.')) {
53
+ continue;
54
+ }
55
+ addApp(entry.name, path.join(scopeDir, entry.name));
56
+ }
57
+ }
58
+
59
+ return apps;
60
+ }
61
+
62
+ /** 解析应用目录:项目内 apps/<name> 优先,回退 node_modules/@bams-app/<name> */
63
+ function resolveAppDir(projectRoot, name) {
64
+ const shortName = toShortName(name);
65
+ const packageName = name.startsWith('@') ? name : `@bams-app/${name}`;
66
+
67
+ const internal = path.join(projectRoot, 'apps', shortName);
68
+ if (isAppDir(internal)) {
69
+ return { dir: internal, source: '项目内 apps/' };
70
+ }
71
+
72
+ try {
73
+ const pkgPath = require.resolve(`${packageName}/package.json`, { paths: [projectRoot] });
74
+ const dir = path.dirname(pkgPath);
75
+ if (isAppDir(dir)) {
76
+ return { dir, source: '依赖包 node_modules' };
77
+ }
78
+ } catch (err) {
79
+ // 未安装该包,交由调用方提示
80
+ }
81
+
82
+ return null;
83
+ }
84
+
85
+ /** 环境标识/路径 -> env 文件(默认 .envs/.env.production) */
86
+ function resolveEnvFile(projectRoot, envInput) {
87
+ if (!envInput) {
88
+ return { filePath: path.join(projectRoot, '.envs', '.env.production') };
89
+ }
90
+
91
+ const isPathLike = envInput.includes('/')
92
+ || envInput.includes('\\')
93
+ || path.basename(envInput).startsWith('.env');
94
+
95
+ if (isPathLike) {
96
+ return { filePath: path.resolve(projectRoot, envInput) };
97
+ }
98
+
99
+ const fileName = envInput === 'production' ? '.env.production' : `.env.dev-${envInput}`;
100
+ return { filePath: path.join(projectRoot, '.envs', fileName) };
101
+ }
102
+
103
+ /** 复用 @bams-app/shared-env 的 env-loader 加载环境变量(含应用私有 .env.<mode> 覆盖) */
104
+ function loadEnvVars(appDir, envFilePath) {
105
+ let loadEnv;
106
+ try {
107
+ ({ loadEnv } = require(require.resolve('@bams-app/shared-env/lib/env-loader', { paths: [appDir, path.dirname(envFilePath)] })));
108
+ } catch (err) {
109
+ warn('未安装 @bams-app/shared-env,跳过环境文件加载');
110
+ return { ...process.env };
111
+ }
112
+
113
+ return loadEnv(appDir, envFilePath);
114
+ }
115
+
116
+ function parseArgs(args) {
117
+ let app = '';
118
+ let envInput = '';
17
119
  let serviceArgs = [];
18
120
  let i = 0;
19
121
 
@@ -22,54 +124,99 @@ async function main(args) {
22
124
  if (arg === '--') {
23
125
  serviceArgs = args.slice(i + 1);
24
126
  break;
25
- } else if (arg === '--component' || arg === '-c') {
26
- component = args[i + 1];
127
+ } else if (arg === '--env' || arg === '-e') {
128
+ envInput = args[i + 1] || '';
27
129
  i += 2;
28
- } else if (arg.startsWith('--')) {
130
+ } else if (arg.startsWith('--env=')) {
131
+ envInput = arg.slice('--env='.length);
132
+ i++;
133
+ } else if (arg.startsWith('-')) {
29
134
  serviceArgs = args.slice(i);
30
135
  break;
31
- } else if (!component) {
32
- component = arg;
136
+ } else if (!app) {
137
+ app = arg;
138
+ i++;
33
139
  } else {
34
140
  serviceArgs = args.slice(i);
35
141
  break;
36
142
  }
37
- i++;
38
143
  }
39
144
 
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');
145
+ return { app, envInput, serviceArgs };
146
+ }
147
+
148
+ async function main(args) {
149
+ const projectRoot = findProjectRoot(process.cwd());
150
+ if (!projectRoot) {
151
+ error('未找到 BAMS-Work 项目(缺少 .bams-work 目录),请先执行 work create <name>');
152
+ process.exit(1);
153
+ }
154
+
155
+ let { app, envInput, serviceArgs } = parseArgs(args);
156
+
157
+ const available = listAvailableApps(projectRoot);
158
+ const printAvailable = () => {
159
+ if (!available.length) {
160
+ error('当前项目未发现可打包应用(需 apps/<app> 或 node_modules/@bams-app/<app>,且含 vue.config.js)');
161
+ return;
162
+ }
163
+ log('可用应用:');
164
+ available.forEach((item) => log(` - ${item.name}`));
165
+ };
166
+
167
+ if (!app) {
168
+ if (available.length === 1) {
169
+ app = available[0].name;
170
+ } else {
171
+ error('请指定要打包的应用: work build <app>');
172
+ printAvailable();
173
+ process.exit(1);
174
+ }
175
+ }
176
+
177
+ const resolved = resolveAppDir(projectRoot, app);
178
+ if (!resolved) {
179
+ error(`未找到应用: ${app}`);
180
+ printAvailable();
47
181
  process.exit(1);
48
182
  }
49
183
 
50
- info(`构建宿主应用,组件: ${component || 'ui-component-demo'}`);
51
- info(`工作目录: ${projectRoot}`);
184
+ const appDir = resolved.dir;
185
+ const appName = toShortName(app);
52
186
 
53
- const uiArgs = [buildAppBin];
54
- if (component) {
55
- uiArgs.push('-c', component);
187
+ let vueCliService;
188
+ try {
189
+ vueCliService = require.resolve('@vue/cli-service/bin/vue-cli-service.js', { paths: [appDir, projectRoot] });
190
+ } catch (err) {
191
+ error('未找到 @vue/cli-service,请先在项目根执行 npm install');
192
+ process.exit(1);
56
193
  }
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
- );
194
+
195
+ const { filePath: envFilePath } = resolveEnvFile(projectRoot, envInput);
196
+ let env;
197
+ if (fs.existsSync(envFilePath)) {
198
+ env = loadEnvVars(appDir, envFilePath);
199
+ info(`环境文件: ${path.relative(projectRoot, envFilePath)}`);
200
+ } else if (envInput) {
201
+ error(`环境文件不存在: ${path.relative(projectRoot, envFilePath)}`);
202
+ process.exit(1);
70
203
  } else {
71
- code = await run(process.execPath, uiArgs, { cwd: projectRoot, env });
204
+ warn(`未找到 ${path.relative(projectRoot, envFilePath)},将使用当前进程环境`);
205
+ env = { ...process.env };
72
206
  }
207
+ env.WORK_PROJECT_ROOT = projectRoot;
208
+ env.NODE_ENV = 'production';
209
+
210
+ info(`打包应用: ${appName}(来源: ${resolved.source})`);
211
+ info(`应用目录: ${appDir}`);
212
+ if (serviceArgs.length) {
213
+ info(`vue-cli 参数: ${serviceArgs.join(' ')}`);
214
+ }
215
+
216
+ const code = await run(process.execPath, [vueCliService, 'build', ...serviceArgs], {
217
+ cwd: appDir,
218
+ env
219
+ });
73
220
  process.exit(code);
74
221
  }
75
222
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bams-app/work-cli",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "BAMS-Work 全局开发工具:复用 work 已发布的包(create-env / create-ui-*)提供项目初始化、组件创建与环境配置能力,开发调试由用户项目本地的 ui-dev-server 承担",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -12,13 +12,20 @@
12
12
  ],
13
13
  "scripts": {
14
14
  "dev:ui": "ui-dev-server",
15
+ "build": "work build",
16
+ "build:bams-app": "work build bams-app",
17
+ "build:project-startr": "work build project-startr",
18
+ "build:touch-startr": "work build touch-startr",
15
19
  "add:component": "work add",
16
20
  "create:env": "work env",
17
21
  "sync:skills": "work skills sync",
18
22
  "postinstall": "work skills sync --quiet || exit 0"
19
23
  },
20
24
  "dependencies": {
21
- "@bams-app/bams-components": "*"
25
+ "@bams-app/bams-app": "*",
26
+ "@bams-app/bams-components": "*",
27
+ "@bams-app/project-startr": "*",
28
+ "@bams-app/touch-startr": "*"
22
29
  },
23
30
  "devDependencies": {
24
31
  "@bams-app/ui-dev-server": "*"