@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/index.js ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+
5
+ module.exports = {
6
+ version: require('./package.json').version,
7
+ bin: path.resolve(__dirname, 'bin', 'work-cli.js')
8
+ };
package/lib/utils.js ADDED
@@ -0,0 +1,196 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { spawn } = require('child_process');
4
+
5
+ const ENABLE_COLOR = process.stdout.isTTY && process.env.NO_COLOR === undefined;
6
+ const ANSI = {
7
+ reset: '\x1b[0m',
8
+ bold: '\x1b[1m',
9
+ red: '\x1b[31m',
10
+ green: '\x1b[32m',
11
+ yellow: '\x1b[33m',
12
+ blue: '\x1b[34m',
13
+ cyan: '\x1b[36m',
14
+ gray: '\x1b[90m'
15
+ };
16
+
17
+ function colorize(text, color) {
18
+ if (!ENABLE_COLOR || !ANSI[color]) {
19
+ return text;
20
+ }
21
+ return `${ANSI[color]}${text}${ANSI.reset}`;
22
+ }
23
+
24
+ function log(msg, color) {
25
+ console.log(color ? colorize(msg, color) : msg);
26
+ }
27
+
28
+ function error(msg) {
29
+ console.error(colorize(`[work-cli] ${msg}`, 'red'));
30
+ }
31
+
32
+ function warn(msg) {
33
+ console.log(colorize(`[work-cli] ${msg}`, 'yellow'));
34
+ }
35
+
36
+ function success(msg) {
37
+ console.log(colorize(`[work-cli] ${msg}`, 'green'));
38
+ }
39
+
40
+ function info(msg) {
41
+ console.log(colorize(`[work-cli] ${msg}`, 'cyan'));
42
+ }
43
+
44
+ function toKebabCase(name) {
45
+ return String(name)
46
+ .trim()
47
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
48
+ .replace(/_/g, '-')
49
+ .toLowerCase();
50
+ }
51
+
52
+ function toPascalCase(name) {
53
+ return toKebabCase(name)
54
+ .replace(/(^|-)([a-z])/g, (_, __, letter) => letter.toUpperCase());
55
+ }
56
+
57
+ function toCamelCase(name) {
58
+ const pascal = toPascalCase(name);
59
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
60
+ }
61
+
62
+ function exists(targetPath) {
63
+ return fs.existsSync(targetPath);
64
+ }
65
+
66
+ function isDirectory(targetPath) {
67
+ return exists(targetPath) && fs.statSync(targetPath).isDirectory();
68
+ }
69
+
70
+ function readJson(filePath) {
71
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
72
+ }
73
+
74
+ function writeJson(filePath, data) {
75
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
76
+ }
77
+
78
+ /**
79
+ * 递归复制目录,跳过 node_modules/.git/dist 等目录
80
+ */
81
+ function copyDir(src, dest, { skip = [] } = {}) {
82
+ const skipDirs = new Set(['node_modules', '.git', 'dist', 'build', ...skip]);
83
+ if (!isDirectory(src)) {
84
+ throw new Error(`源目录不存在: ${src}`);
85
+ }
86
+ fs.mkdirSync(dest, { recursive: true });
87
+
88
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
89
+ const srcPath = path.join(src, entry.name);
90
+ const destPath = path.join(dest, entry.name);
91
+
92
+ if (entry.isDirectory()) {
93
+ if (skipDirs.has(entry.name)) {
94
+ continue;
95
+ }
96
+ copyDir(srcPath, destPath, { skip });
97
+ } else {
98
+ fs.copyFileSync(srcPath, destPath);
99
+ }
100
+ }
101
+ }
102
+
103
+ /**
104
+ * 递归遍历目录,返回文件路径列表
105
+ */
106
+ function walkFiles(dir, result = []) {
107
+ if (!isDirectory(dir)) {
108
+ return result;
109
+ }
110
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
111
+ const fullPath = path.join(dir, entry.name);
112
+ if (entry.isDirectory()) {
113
+ walkFiles(fullPath, result);
114
+ } else {
115
+ result.push(fullPath);
116
+ }
117
+ }
118
+ return result;
119
+ }
120
+
121
+ /**
122
+ * 在目录内所有文本文件中执行字符串替换
123
+ */
124
+ function replaceInDir(dir, replacements, { excludes = [] } = {}) {
125
+ const files = walkFiles(dir).filter((filePath) => {
126
+ return !excludes.some((pattern) => filePath.endsWith(pattern));
127
+ });
128
+ for (const filePath of files) {
129
+ const content = fs.readFileSync(filePath, 'utf8');
130
+ let next = content;
131
+ for (const [from, to] of Object.entries(replacements)) {
132
+ next = next.split(from).join(to);
133
+ }
134
+ if (next !== content) {
135
+ fs.writeFileSync(filePath, next, 'utf8');
136
+ }
137
+ }
138
+ }
139
+
140
+ /**
141
+ * 从当前目录向上查找用户项目根(含 .bams-work 目录的最近祖先)
142
+ */
143
+ function findProjectRoot(startDir = process.cwd()) {
144
+ let current = path.resolve(startDir);
145
+ while (true) {
146
+ if (isDirectory(path.join(current, '.bams-work'))) {
147
+ return current;
148
+ }
149
+ const parent = path.dirname(current);
150
+ if (parent === current) {
151
+ return null;
152
+ }
153
+ current = parent;
154
+ }
155
+ }
156
+
157
+ /**
158
+ * 启动子进程(继承 stdio)
159
+ */
160
+ function run(command, args, { cwd, env = process.env } = {}) {
161
+ return new Promise((resolve) => {
162
+ const child = spawn(command, args, {
163
+ cwd,
164
+ env,
165
+ stdio: 'inherit'
166
+ });
167
+ child.on('error', (err) => {
168
+ error(`启动失败: ${err.message}`);
169
+ resolve(1);
170
+ });
171
+ child.on('exit', (code) => {
172
+ resolve(code ?? 1);
173
+ });
174
+ });
175
+ }
176
+
177
+ module.exports = {
178
+ colorize,
179
+ log,
180
+ error,
181
+ warn,
182
+ success,
183
+ info,
184
+ toKebabCase,
185
+ toPascalCase,
186
+ toCamelCase,
187
+ exists,
188
+ isDirectory,
189
+ readJson,
190
+ writeJson,
191
+ copyDir,
192
+ walkFiles,
193
+ replaceInDir,
194
+ findProjectRoot,
195
+ run
196
+ };
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@bams-app/work-cli",
3
+ "version": "0.0.1",
4
+ "description": "BAMS-Work 全局开发工具:复用 work 已发布的包(ui-dev-server / shared-env / create-ui-*)提供项目初始化与组件开发能力(类似 vue-cli)",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "bams-work": "./bin/work-cli.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "commands",
12
+ "lib",
13
+ "templates"
14
+ ],
15
+ "dependencies": {
16
+ "@bams-app/create-env": "*",
17
+ "@bams-app/create-pages-entry": "*",
18
+ "@bams-app/create-pages-from-components": "*",
19
+ "@bams-app/create-ui-base": "*",
20
+ "@bams-app/create-ui-component": "*",
21
+ "@bams-app/create-ui-page": "*",
22
+ "@bams-app/shared-env": "*",
23
+ "@bams-app/ui-dev-server": "*"
24
+ },
25
+ "engines": {
26
+ "node": ">=16.7.0"
27
+ },
28
+ "license": "UNLICENSED"
29
+ }
@@ -0,0 +1,14 @@
1
+ # 开发环境(示例),可复制为 .env.dev-<标识> 使用
2
+ # 端口必须与 PROXY_TARGET 的端口保持一致
3
+ NODE_ENV=development
4
+ PORT=8088
5
+ PROXY_TARGET=http://127.0.0.1:8088
6
+ BASE_URL=/
7
+
8
+ VUE_APP_TITLE=BAMS组件开发环境
9
+ VUE_APP_SYS_CODE=bams-demo
10
+ VUE_APP_SYS_NAME=BAMS组件开发示例
11
+
12
+ # 可配置插槽(可选,留空使用默认空组件)
13
+ # COMPONENT_LOGIN=@bams-app/ui-login-component
14
+ # COMPONENT_STARTR_LAYOUT=@bams-app/ui-startr-layout-component
@@ -0,0 +1,45 @@
1
+ # 项目环境配置
2
+
3
+ 本目录存放各业务系统环境变量,`bams-work dev <env>` 会加载 `.env.dev-<env>`。
4
+
5
+ ## 环境文件格式
6
+
7
+ - `.env.dev-demo`:开发环境示例(跟随本模板生成)
8
+ - `.env.production`:生产环境(构建时加载)
9
+
10
+ ## 关键变量
11
+
12
+ | 变量名 | 说明 |
13
+ | ------------------------- | ---------------------------------------- |
14
+ | `PROXY_TARGET` | 开发代理目标地址(后端服务) |
15
+ | `PORT` | 开发服务器端口,需与代理目标端口一致 |
16
+ | `BASE_URL` | 应用基础路径 |
17
+ | `VUE_APP_TITLE` | 浏览器标签页标题 |
18
+ | `VUE_APP_SYS_CODE` | 系统编码 |
19
+ | `COMPONENT_LOGIN` | 登录组件包名(可配置插槽) |
20
+ | `COMPONENT_STARTR_LAYOUT` | 布局组件包名(可配置插槽) |
21
+ | `VUE_APP_*` | 注入前端代码的编译变量(勿存放敏感信息) |
22
+
23
+ ## 创建新环境
24
+
25
+ ```bash
26
+ # 复制示例
27
+ cd .envs
28
+ cp .env.dev-demo .env.dev-<新标识>
29
+ ```
30
+
31
+ > 命名规范:`.env.dev-<标识>`,标识仅允许小写字母、数字和连字符。
32
+
33
+ ## 代理配置
34
+
35
+ 默认内置代理前缀:`/bams-assets`、`/bams-ui-umd`、`/bams-app`、`/admin-api`、`/preview`。
36
+
37
+ 如需自定义代理,在项目根创建 `.proxy.js`:
38
+
39
+ ```js
40
+ module.exports = {
41
+ proxy: {
42
+ '/my-api': { target: 'http://192.168.1.100:8080', changeOrigin: true }
43
+ }
44
+ };
45
+ ```
@@ -0,0 +1,11 @@
1
+ /**
2
+ * BAMS-Work 自定义开发代理(可选)
3
+ * 存在本文件时自动生效,覆盖内置默认代理前缀。
4
+ * 也可导出函数:module.exports = ({ env, projectRoot }) => ({ proxy: { ... } })
5
+ */
6
+ module.exports = {
7
+ proxy: {
8
+ // 示例:自定义后端前缀
9
+ // '/my-api': { target: 'http://192.168.1.100:8080', changeOrigin: true }
10
+ }
11
+ };
@@ -0,0 +1,58 @@
1
+ # BAMS-Work Monorepo 项目
2
+
3
+ 基于 `@bams-app/work-cli` 初始化的组件开发项目(类似 vue-cli 模式)。
4
+ work 开发环境(`@bams-app/ui-dev-server`)与创建命令(`@bams-app/create-ui-*`)直接复用 work 仓库发布的 npm 包。
5
+
6
+ ## 目录结构
7
+
8
+ ```
9
+ .
10
+ ├── package.json # Monorepo 根(workspaces: bams-components/*、*-ui/*、bams-ui)
11
+ ├── .bams-work/ # BAMS-Work 项目标记目录,勿删除
12
+ ├── .envs/ # 环境配置(.env.dev-<env>)
13
+ ├── .proxy.js # 自定义开发代理(可选)
14
+ ├── bams-components/ # 默认组件 scope
15
+ │ └── ui-component-demo # 示例组件
16
+ └── <scope>-ui/ # 业务 scope 目录(如 energy-ui/,add 时创建)
17
+ └── ui-xxx
18
+ ```
19
+
20
+ ## 常用命令
21
+
22
+ ```bash
23
+ # 开发(加载 .envs/.env.dev-<env>,默认组件 ui-component-demo)
24
+ bams-work dev demo
25
+ bams-work dev demo ui-order-list
26
+
27
+ # 构建宿主应用(production,输出 dist/)
28
+ bams-work build ui-order-list
29
+
30
+ # 构建组件 UMD 产物(输出 dist/umd/)
31
+ bams-work umd ui-order-list
32
+
33
+ # 在 scope 目录下创建新组件
34
+ bams-work add --dir energy-ui --name ui-order-list
35
+ bams-work add --dir energy-ui --name page-order-list --type page
36
+ ```
37
+
38
+ ## 首次安装
39
+
40
+ ```bash
41
+ npm install
42
+ # 或
43
+ yarn install
44
+ ```
45
+
46
+ `@bams-app/ui-dev-server` 及其依赖的能力包(`@bams-app/components` 等)会安装到根 node_modules,
47
+ 业务组件与 work 开发环境共用同一套能力实例。项目 `.npmrc` 配置了 `install-links=true`,
48
+ `file:` 安装的能力包会以复制方式解析其全部传递依赖(vue、ant-design-vue 等自动安装),
49
+ 因此 `package.json` 无需声明任何外部运行时依赖。
50
+
51
+ ## 环境变量
52
+
53
+ 见 `.envs/README.md`。新增环境:`cp .envs/.env.dev-demo .envs/.env.dev-<标识>`。
54
+
55
+ ## 自定义配置
56
+
57
+ - 代理:创建项目根 `.proxy.js`(见 `.proxy.js.example`)
58
+ - webpack 扩展:创建项目根 `vue.config.extend.js`(导出对象或 `({ env, projectRoot }) => 对象`)
@@ -0,0 +1,35 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Build outputs
5
+ dist/
6
+ build/
7
+ *.log
8
+
9
+ # BAMS-Work 内部产物(install 时由 .bams-work 重新生成)
10
+ .bams-work/
11
+
12
+ # IDE
13
+ .vscode/
14
+ .idea/
15
+ .trae/
16
+ *.swp
17
+ *.swo
18
+ *~
19
+
20
+ # OS
21
+ .DS_Store
22
+ Thumbs.db
23
+
24
+ # Environment
25
+ .env
26
+ .env.local
27
+ .env.*.local
28
+
29
+ # Yarn
30
+ .yarn/*
31
+ !.yarn/patches
32
+ !.yarn/plugins
33
+ !.yarn/releases
34
+ !.yarn/sdks
35
+ !.yarn/versions
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "__PROJECT_NAME__",
3
+ "version": "0.0.6",
4
+ "private": true,
5
+ "description": "BAMS-Work Monorepo 项目",
6
+ "workspaces": [
7
+ "bams-components/*",
8
+ "*-ui/*",
9
+ "bams-ui"
10
+ ],
11
+ "scripts": {
12
+ "dev": "bams-work dev",
13
+ "build": "bams-work build",
14
+ "umd": "bams-work umd",
15
+ "add": "bams-work add"
16
+ },
17
+ "dependencies": {
18
+ __UI_DEV_SERVER_DEP____CAPABILITY_DEPS__
19
+ }
20
+ }