@sys-designer/create-vue 1.0.2 → 1.0.3
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/package.json
CHANGED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# 若文件含 CRLF(Windows 拷贝 / git autocrlf 导致),自动转 LF 后重跑。
|
|
3
|
+
# 本自修正必须放在第 2 行(shebang 之后、任何注释/命令之前),确保最先执行。
|
|
4
|
+
# 约束:
|
|
5
|
+
# 1) 必须用纯 && 链式,不能写 if/then/fi —— CRLF 会让 then 失效,自修正无法触发。
|
|
6
|
+
# 2) 不能用 grep 检测 CR —— Git Bash 的 grep 以文本模式读文件,会把 CRLF 的 CR 剥离,检测永远失败。
|
|
7
|
+
# 3) 不能用 sed 's/\r$//' —— Git Bash 的 GNU sed 正则不识别 \r。
|
|
8
|
+
# 故采用「字节数对比」:tr 去掉所有 CR 后字节数变少,说明原文件含 CRLF。
|
|
9
|
+
n1=$(wc -c < "$0"); tr -d '\r' < "$0" > "$0.tmp"; n2=$(wc -c < "$0.tmp"); [ "$n1" != "$n2" ] && mv "$0.tmp" "$0" && exec bash "$0" "$@"; rm -f "$0.tmp"
|
|
10
|
+
|
|
11
|
+
# build.sh —— 构建项目并将产物打包为压缩包,输出到 output/ 目录
|
|
12
|
+
#
|
|
13
|
+
# 用法:
|
|
14
|
+
# bash scripts/build.sh # 输出到 ./output/<name>-<version>.tar.gz
|
|
15
|
+
# bash scripts/build.sh myapp # 输出到 ./output/myapp.tar.gz
|
|
16
|
+
# bash scripts/build.sh /path/out # 输出目录改为 /path/out
|
|
17
|
+
# bash scripts/build.sh /path/out myapp # 输出目录 /path/out,名称 myapp
|
|
18
|
+
# bash scripts/build.sh --name myapp --out /path/out
|
|
19
|
+
#
|
|
20
|
+
# 说明:
|
|
21
|
+
# - 自动选择包管理器(按 lockfile 判定,优先 pnpm/yarn/npm);含 pnpm 的 link: 等协议时
|
|
22
|
+
# 必须用 pnpm,否则 npm 会报 EUNSUPPORTEDPROTOCOL。也可用 PKG_MANAGER 环境变量强制指定。
|
|
23
|
+
# - 执行 安装 + 构建,产物在 dist/。
|
|
24
|
+
# - 安装后会把 package.json 中所有 link: 依赖的 lib.config.ts 合并,
|
|
25
|
+
# 输出到 common/lib.config.ts(由 scripts/merge-lib-config.mjs 处理)。
|
|
26
|
+
# - 包名默认取 package.json 的 name-version;可用第二位置参数或 --name 指定。
|
|
27
|
+
# - 输出目录默认 ./output;可用第一位置参数(像路径)或 --out 指定。
|
|
28
|
+
# - 若环境存在 zip 命令,会额外生成一个同名 .zip 包。
|
|
29
|
+
# - 若脚本从 Windows 拷贝带 CRLF 行尾,本脚本会自动转为 LF 后重新执行。
|
|
30
|
+
|
|
31
|
+
set -euo pipefail
|
|
32
|
+
|
|
33
|
+
# 切到项目根目录(scripts/ 的上一级)
|
|
34
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
35
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
36
|
+
cd "$PROJECT_ROOT"
|
|
37
|
+
|
|
38
|
+
# 选择包管理器:优先按项目里的 lockfile 判定,避免 npm 不识别 pnpm 的 link: 等协议
|
|
39
|
+
# (会报 EUNSUPPORTEDPROTOCOL)。也可用环境变量 PKG_MANAGER=npm|pnpm|yarn 强制指定。
|
|
40
|
+
detect_pm() {
|
|
41
|
+
if [ -n "${PKG_MANAGER:-}" ]; then
|
|
42
|
+
PM="$PKG_MANAGER"
|
|
43
|
+
elif [ -f pnpm-lock.yaml ]; then
|
|
44
|
+
PM=pnpm
|
|
45
|
+
elif [ -f yarn.lock ]; then
|
|
46
|
+
PM=yarn
|
|
47
|
+
elif [ -f package-lock.json ]; then
|
|
48
|
+
PM=npm
|
|
49
|
+
elif command -v pnpm >/dev/null 2>&1; then
|
|
50
|
+
PM=pnpm
|
|
51
|
+
elif command -v yarn >/dev/null 2>&1; then
|
|
52
|
+
PM=yarn
|
|
53
|
+
else
|
|
54
|
+
PM=npm
|
|
55
|
+
fi
|
|
56
|
+
case "$PM" in
|
|
57
|
+
pnpm) PM_INSTALL="pnpm install"; PM_RUN="pnpm run" ;;
|
|
58
|
+
yarn) PM_INSTALL="yarn install"; PM_RUN="yarn" ;;
|
|
59
|
+
*) PM_INSTALL="npm install"; PM_RUN="npm run" ;;
|
|
60
|
+
esac
|
|
61
|
+
}
|
|
62
|
+
detect_pm
|
|
63
|
+
|
|
64
|
+
OUT_DIR="$PROJECT_ROOT/output"
|
|
65
|
+
ARCHIVE_NAME=""
|
|
66
|
+
POSITIONAL=()
|
|
67
|
+
while [ "$#" -gt 0 ]; do
|
|
68
|
+
case "$1" in
|
|
69
|
+
$'\r') shift ;; # 丢弃 CRLF 自修正重跑时可能带入的孤立 CR 参数
|
|
70
|
+
--name) ARCHIVE_NAME="${2:-}"; shift 2 ;;
|
|
71
|
+
--name=*) ARCHIVE_NAME="${1#*=}"; shift ;;
|
|
72
|
+
--out) OUT_DIR="${2:-}"; shift 2 ;;
|
|
73
|
+
--out=*) OUT_DIR="${1#*=}"; shift ;;
|
|
74
|
+
-*) echo "未知参数: $1" >&2; exit 1 ;;
|
|
75
|
+
*) POSITIONAL+=("$1"); shift ;;
|
|
76
|
+
esac
|
|
77
|
+
done
|
|
78
|
+
|
|
79
|
+
# 位置参数兜底: $1 = 输出目录(像路径) 或 名称, $2 = 名称
|
|
80
|
+
if [ -z "$ARCHIVE_NAME" ] && [ "${#POSITIONAL[@]}" -ge 1 ]; then
|
|
81
|
+
first="${POSITIONAL[0]}"
|
|
82
|
+
if [ "${#POSITIONAL[@]}" -ge 2 ]; then
|
|
83
|
+
OUT_DIR="$first"; ARCHIVE_NAME="${POSITIONAL[1]}"
|
|
84
|
+
else
|
|
85
|
+
case "$first" in
|
|
86
|
+
/*|./*|../*|*/|*/*) OUT_DIR="$first" ;;
|
|
87
|
+
*) ARCHIVE_NAME="$first" ;;
|
|
88
|
+
esac
|
|
89
|
+
fi
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
echo "==> 工作目录: $PROJECT_ROOT"
|
|
93
|
+
|
|
94
|
+
echo "==> 安装依赖 ($PM_INSTALL)"
|
|
95
|
+
$PM_INSTALL
|
|
96
|
+
|
|
97
|
+
# 合并所有 link: 依赖(如 new-app)的 lib.config.ts -> common/lib.config.ts
|
|
98
|
+
echo "==> 合并 link 依赖的 lib.config.ts"
|
|
99
|
+
node "$(dirname "$0")/merge-lib-config.mjs"
|
|
100
|
+
|
|
101
|
+
echo "==> 构建生产包 ($PM_RUN build)"
|
|
102
|
+
$PM_RUN build
|
|
103
|
+
|
|
104
|
+
DIST_DIR="$PROJECT_ROOT/dist"
|
|
105
|
+
if [ ! -d "$DIST_DIR" ]; then
|
|
106
|
+
echo "错误: 构建产物目录 $DIST_DIR 不存在,构建可能失败。" >&2
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# 读取包名与版本(构建依赖 node,必可用);未指定名称时作为默认名
|
|
111
|
+
PKG_NAME=$(node -p "require('./package.json').name" 2>/dev/null || echo app)
|
|
112
|
+
PKG_VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo 1.0.0)
|
|
113
|
+
if [ -z "$ARCHIVE_NAME" ]; then
|
|
114
|
+
ARCHIVE_NAME="$PKG_NAME-$PKG_VERSION"
|
|
115
|
+
else
|
|
116
|
+
# 去掉用户可能带入的扩展名,避免双重后缀
|
|
117
|
+
ARCHIVE_NAME="${ARCHIVE_NAME%.tar.gz}"
|
|
118
|
+
ARCHIVE_NAME="${ARCHIVE_NAME%.tgz}"
|
|
119
|
+
ARCHIVE_NAME="${ARCHIVE_NAME%.zip}"
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
mkdir -p "$OUT_DIR"
|
|
123
|
+
TAR_ARCHIVE="$OUT_DIR/$ARCHIVE_NAME.tar.gz"
|
|
124
|
+
|
|
125
|
+
echo "==> 打包 dist/ -> $TAR_ARCHIVE"
|
|
126
|
+
tar -czf "$TAR_ARCHIVE" -C "$DIST_DIR" .
|
|
127
|
+
|
|
128
|
+
# 若环境有 zip,额外生成 zip 包
|
|
129
|
+
if command -v zip >/dev/null 2>&1; then
|
|
130
|
+
ZIP_ARCHIVE="$OUT_DIR/$ARCHIVE_NAME.zip"
|
|
131
|
+
echo "==> 打包 dist/ -> $ZIP_ARCHIVE"
|
|
132
|
+
(cd "$DIST_DIR" && zip -r -q "$ZIP_ARCHIVE" .)
|
|
133
|
+
else
|
|
134
|
+
echo "==> 未检测到 zip 命令,跳过 zip 包(已生成 tar.gz)"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
echo "==> 构建完成,压缩包输出在: $OUT_DIR"
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# 若文件含 CRLF(Windows 拷贝 / git autocrlf 导致),自动转 LF 后重跑。
|
|
3
|
+
# 本自修正必须放在第 2 行(shebang 之后、任何注释/命令之前),确保最先执行。
|
|
4
|
+
# 约束:
|
|
5
|
+
# 1) 必须用纯 && 链式,不能写 if/then/fi —— CRLF 会让 then 失效,自修正无法触发。
|
|
6
|
+
# 2) 不能用 grep 检测 CR —— Git Bash 的 grep 以文本模式读文件,会把 CRLF 的 CR 剥离,检测永远失败。
|
|
7
|
+
# 3) 不能用 sed 's/\r$//' —— Git Bash 的 GNU sed 正则不识别 \r。
|
|
8
|
+
# 故采用「字节数对比」:tr 去掉所有 CR 后字节数变少,说明原文件含 CRLF。
|
|
9
|
+
n1=$(wc -c < "$0"); tr -d '\r' < "$0" > "$0.tmp"; n2=$(wc -c < "$0.tmp"); [ "$n1" != "$n2" ] && mv "$0.tmp" "$0" && exec bash "$0" "$@"; rm -f "$0.tmp"
|
|
10
|
+
|
|
11
|
+
# deploy.sh —— 仅发布(解压)已由 build.sh 构建好的压缩包到 nginx html 目录
|
|
12
|
+
#
|
|
13
|
+
# 用法:
|
|
14
|
+
# bash scripts/deploy.sh # 仅发布 output/ 中已有的压缩包到自动检测的 nginx 目录
|
|
15
|
+
# bash scripts/deploy.sh /usr/share/nginx/html # 发布到指定 nginx 目录
|
|
16
|
+
# bash scripts/deploy.sh /usr/share/nginx/html myapp # 发布到 nginx 的 myapp 子目录
|
|
17
|
+
# bash scripts/deploy.sh myapp # 自动检测 nginx 目录, 发布到其 myapp 子目录
|
|
18
|
+
#
|
|
19
|
+
# 说明:
|
|
20
|
+
# - 本脚本【不负责构建】,只能使用 build.sh 已在 output/ 下生成的压缩包。
|
|
21
|
+
# 若找不到压缩包会直接报错,请先运行: bash scripts/build.sh
|
|
22
|
+
# - 发布时把压缩包【解压】到目标 nginx 静态目录(可直接 serve), 不拷贝 .tar.gz。
|
|
23
|
+
# - 未传 nginx 目录时尝试自动检测常见目录; 检测到才发布, 否则仅提示压缩包位置。
|
|
24
|
+
# - --clean 会先清空目标目录(或子目录)现有内容。
|
|
25
|
+
# - 若脚本从 Windows 拷贝带 CRLF 行尾, 本脚本会自动转为 LF 后重新执行。
|
|
26
|
+
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
|
|
29
|
+
# 切到项目根目录(scripts/ 的上一级)
|
|
30
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
31
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
32
|
+
cd "$PROJECT_ROOT"
|
|
33
|
+
|
|
34
|
+
DEPLOY_DIR=""
|
|
35
|
+
SUBDIR=""
|
|
36
|
+
ARCHIVE_NAME=""
|
|
37
|
+
CLEAN=0
|
|
38
|
+
POSITIONAL=()
|
|
39
|
+
while [ "$#" -gt 0 ]; do
|
|
40
|
+
case "$1" in
|
|
41
|
+
$'\r') shift ;; # 丢弃 CRLF 自修正重跑时可能带入的孤立 CR 参数
|
|
42
|
+
--name) ARCHIVE_NAME="${2:-}"; shift 2 ;;
|
|
43
|
+
--name=*) ARCHIVE_NAME="${1#*=}"; shift ;;
|
|
44
|
+
--clean) CLEAN=1; shift ;;
|
|
45
|
+
-*) echo "未知参数: $1" >&2; exit 1 ;;
|
|
46
|
+
*) POSITIONAL+=("$1"); shift ;;
|
|
47
|
+
esac
|
|
48
|
+
done
|
|
49
|
+
|
|
50
|
+
# 位置参数: $1 = nginx 目录(可选, 省略则自动检测), $2 = 子目录名(可选)
|
|
51
|
+
if [ "${#POSITIONAL[@]}" -ge 1 ]; then
|
|
52
|
+
first="${POSITIONAL[0]}"
|
|
53
|
+
if [ "${#POSITIONAL[@]}" -ge 2 ]; then
|
|
54
|
+
DEPLOY_DIR="$first"; SUBDIR="${POSITIONAL[1]}"
|
|
55
|
+
else
|
|
56
|
+
case "$first" in
|
|
57
|
+
# 含路径分隔符(/ 或 \)的视为目标目录;否则视为 nginx 下的子目录名
|
|
58
|
+
/*|./*|../*|*/|*/*|*\\*) DEPLOY_DIR="$first" ;;
|
|
59
|
+
*) SUBDIR="$first" ;;
|
|
60
|
+
esac
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
echo "==> 工作目录: $PROJECT_ROOT"
|
|
65
|
+
|
|
66
|
+
# 若未显式指定目录,尝试自动检测常见的 nginx html 目录
|
|
67
|
+
if [ -z "$DEPLOY_DIR" ]; then
|
|
68
|
+
for d in /usr/share/nginx/html /var/www/html /usr/local/nginx/html /opt/nginx/html /data/nginx/html; do
|
|
69
|
+
if [ -d "$d" ]; then
|
|
70
|
+
DEPLOY_DIR="$d"
|
|
71
|
+
echo "==> 未指定目录,自动检测到 nginx html 目录: $DEPLOY_DIR"
|
|
72
|
+
break
|
|
73
|
+
fi
|
|
74
|
+
done
|
|
75
|
+
if [ -z "$DEPLOY_DIR" ]; then
|
|
76
|
+
echo "==> 未指定目录且未检测到 nginx html 目录,将只保留压缩包不发布"
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# 读取包名与版本(node 必可用),用于推导压缩包名
|
|
81
|
+
PKG_NAME=$(node -p "require('./package.json').name" 2>/dev/null || echo app)
|
|
82
|
+
PKG_VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo 1.0.0)
|
|
83
|
+
if [ -z "$ARCHIVE_NAME" ]; then
|
|
84
|
+
ARCHIVE_NAME="$PKG_NAME-$PKG_VERSION"
|
|
85
|
+
else
|
|
86
|
+
# 去掉用户可能带入的扩展名,避免双重后缀
|
|
87
|
+
ARCHIVE_NAME="${ARCHIVE_NAME%.tar.gz}"
|
|
88
|
+
ARCHIVE_NAME="${ARCHIVE_NAME%.tgz}"
|
|
89
|
+
ARCHIVE_NAME="${ARCHIVE_NAME%.zip}"
|
|
90
|
+
fi
|
|
91
|
+
TAR_ARCHIVE="$PROJECT_ROOT/output/$ARCHIVE_NAME.tar.gz"
|
|
92
|
+
|
|
93
|
+
# 本脚本不构建,必须使用 build.sh 已生成的压缩包
|
|
94
|
+
if [ ! -f "$TAR_ARCHIVE" ]; then
|
|
95
|
+
echo "错误: 未找到构建好的压缩包 $TAR_ARCHIVE" >&2
|
|
96
|
+
echo " deploy.sh 不负责构建,请先运行: bash scripts/build.sh" >&2
|
|
97
|
+
exit 1
|
|
98
|
+
fi
|
|
99
|
+
echo "==> 使用构建好的压缩包: $TAR_ARCHIVE"
|
|
100
|
+
|
|
101
|
+
if [ -n "$DEPLOY_DIR" ]; then
|
|
102
|
+
# 统一用 / 作为分隔符,避免 Windows 反斜杠路径与子目录 / 拼接时混用导致 mkdir/tar 失败
|
|
103
|
+
DEPLOY_DIR="${DEPLOY_DIR//\\//}"
|
|
104
|
+
# nginx 根目录必须存在;不存在则报错,避免 mkdir -p 误建出假的 nginx 目录
|
|
105
|
+
if [ ! -d "$DEPLOY_DIR" ]; then
|
|
106
|
+
echo "错误: nginx 目录不存在: $DEPLOY_DIR" >&2
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
TARGET="$DEPLOY_DIR"
|
|
110
|
+
if [ -n "$SUBDIR" ]; then
|
|
111
|
+
TARGET="$DEPLOY_DIR/$SUBDIR"
|
|
112
|
+
# 子目录不存在时自动创建(nginx 目录已存在的前提下)
|
|
113
|
+
if [ ! -d "$TARGET" ]; then
|
|
114
|
+
echo "==> 目标子目录不存在,自动创建: $TARGET"
|
|
115
|
+
fi
|
|
116
|
+
echo "==> 目标子目录: $SUBDIR"
|
|
117
|
+
fi
|
|
118
|
+
echo "==> 解压压缩包到目标目录(nginx 可直接 serve): $TARGET"
|
|
119
|
+
mkdir -p "$TARGET"
|
|
120
|
+
if [ "$CLEAN" -eq 1 ]; then
|
|
121
|
+
echo "==> 清空目标目录现有内容"
|
|
122
|
+
find "$TARGET" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
|
|
123
|
+
fi
|
|
124
|
+
tar -xzf "$TAR_ARCHIVE" -C "$TARGET"
|
|
125
|
+
echo "==> 已发布(解压): $TARGET"
|
|
126
|
+
else
|
|
127
|
+
echo "==> 压缩包已就绪: $TAR_ARCHIVE (未指定发布目录,跳过发布)"
|
|
128
|
+
fi
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// merge-lib-config.mjs
|
|
3
|
+
// 读取项目 package.json 中所有 "xxx": "link:../xxx" 依赖,逐个解析其 lib.config.ts,
|
|
4
|
+
// 把其中的 libResolves / libModules 合并后输出到 <项目根>/common/lib.config.ts。
|
|
5
|
+
//
|
|
6
|
+
// 用法: node scripts/merge-lib-config.mjs
|
|
7
|
+
// - 在 build.sh 中于 install 之后、build 之前被调用。
|
|
8
|
+
// - 即使没有任何 link: 依赖 / 没有可合并的 lib.config.ts,也会输出一个空的
|
|
9
|
+
// common/lib.config.ts(不跳过),保证下游构建始终有该文件可用。
|
|
10
|
+
// - resolve 参数保留原样(如 resolve(process.cwd(), '.', './node_modules/...'))。
|
|
11
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
12
|
+
import { resolve as pathResolve, join } from 'node:path';
|
|
13
|
+
|
|
14
|
+
const projectRoot = process.cwd();
|
|
15
|
+
|
|
16
|
+
// 1) 读取 package.json,找出所有 link: 依赖
|
|
17
|
+
const pkgPath = join(projectRoot, 'package.json');
|
|
18
|
+
const linkDirs = [];
|
|
19
|
+
if (!existsSync(pkgPath)) {
|
|
20
|
+
console.log('merge-lib-config: 未找到 package.json,将输出空的 common/lib.config.ts');
|
|
21
|
+
} else {
|
|
22
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
23
|
+
const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
24
|
+
for (const [name, spec] of Object.entries(deps)) {
|
|
25
|
+
if (typeof spec === 'string' && spec.startsWith('link:')) {
|
|
26
|
+
const rel = spec.slice('link:'.length);
|
|
27
|
+
linkDirs.push({ name, path: pathResolve(projectRoot, rel) });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (linkDirs.length === 0) {
|
|
31
|
+
console.log('merge-lib-config: 未找到 link: 依赖,将输出空的 common/lib.config.ts');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 2) 解析单个 lib.config.ts 的 libResolves / libModules
|
|
36
|
+
function parseLibConfig(content) {
|
|
37
|
+
const resolves = {};
|
|
38
|
+
const modules = [];
|
|
39
|
+
|
|
40
|
+
// libResolves = { ... }
|
|
41
|
+
const resMatch = content.match(/export\s+const\s+libResolves\s*=\s*\{([\s\S]*?)\n\s*\};/);
|
|
42
|
+
if (resMatch) {
|
|
43
|
+
for (const line of resMatch[1].split('\n')) {
|
|
44
|
+
const m = line.match(/'([^']+)'\s*:\s*([\s\S]+?)\s*,?\s*$/);
|
|
45
|
+
if (m) resolves[m[1]] = m[2].trim();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// libModules = [ ... ]
|
|
50
|
+
const modMatch = content.match(/export\s+const\s+libModules\s*=\s*\[([\s\S]*?)\n\s*\];/);
|
|
51
|
+
if (modMatch) {
|
|
52
|
+
const reObj = /\{([\s\S]*?)\}/g;
|
|
53
|
+
let m;
|
|
54
|
+
while ((m = reObj.exec(modMatch[1])) !== null) {
|
|
55
|
+
const entry = {};
|
|
56
|
+
const propRe = /(\w+)\s*:\s*(true|false|'([^']*)')/g;
|
|
57
|
+
let p;
|
|
58
|
+
while ((p = propRe.exec(m[1])) !== null) {
|
|
59
|
+
const key = p[1];
|
|
60
|
+
if (p[2] === 'true') entry[key] = true;
|
|
61
|
+
else if (p[2] === 'false') entry[key] = false;
|
|
62
|
+
else entry[key] = p[3];
|
|
63
|
+
}
|
|
64
|
+
if (entry.name) modules.push(entry);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return { resolves, modules };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 3) 合并(resolves 按 key 去重取先到者;modules 按 name 去重)
|
|
72
|
+
const mergedResolves = {};
|
|
73
|
+
const mergedModules = [];
|
|
74
|
+
const seenModules = new Set();
|
|
75
|
+
let conflictWarned = false;
|
|
76
|
+
|
|
77
|
+
for (const { name, path } of linkDirs) {
|
|
78
|
+
const cfgPath = join(path, 'lib.config.ts');
|
|
79
|
+
if (!existsSync(cfgPath)) {
|
|
80
|
+
console.log(`merge-lib-config: [${name}] 未找到 lib.config.ts,跳过: ${cfgPath}`);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const { resolves, modules } = parseLibConfig(readFileSync(cfgPath, 'utf-8'));
|
|
84
|
+
for (const [k, v] of Object.entries(resolves)) {
|
|
85
|
+
if (k in mergedResolves) {
|
|
86
|
+
if (!conflictWarned) {
|
|
87
|
+
console.warn(`merge-lib-config: libResolves 键 "${k}" 重复,保留首个定义`);
|
|
88
|
+
conflictWarned = true;
|
|
89
|
+
}
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
mergedResolves[k] = v;
|
|
93
|
+
}
|
|
94
|
+
for (const mod of modules) {
|
|
95
|
+
if (seenModules.has(mod.name)) continue;
|
|
96
|
+
seenModules.add(mod.name);
|
|
97
|
+
mergedModules.push(mod);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 4) 渲染并写出到 common/lib.config.ts
|
|
102
|
+
function render() {
|
|
103
|
+
const lines = [];
|
|
104
|
+
if (Object.keys(mergedResolves).length > 0) {
|
|
105
|
+
lines.push("import { resolve } from 'path';");
|
|
106
|
+
lines.push('');
|
|
107
|
+
}
|
|
108
|
+
lines.push('export const libResolves = {');
|
|
109
|
+
for (const [k, v] of Object.entries(mergedResolves)) {
|
|
110
|
+
lines.push(` '${k}': ${v},`);
|
|
111
|
+
}
|
|
112
|
+
lines.push('};');
|
|
113
|
+
lines.push('');
|
|
114
|
+
lines.push('export const libModules = [');
|
|
115
|
+
for (const mod of mergedModules) {
|
|
116
|
+
const props = Object.entries(mod)
|
|
117
|
+
.map(([k, val]) => (val === true ? `${k}: true` : val === false ? `${k}: false` : `${k}: '${val}'`))
|
|
118
|
+
.join(', ');
|
|
119
|
+
lines.push(` { ${props} },`);
|
|
120
|
+
}
|
|
121
|
+
lines.push('];');
|
|
122
|
+
return lines.join('\n') + '\n';
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const outDir = join(projectRoot, 'common');
|
|
126
|
+
mkdirSync(outDir, { recursive: true });
|
|
127
|
+
const outPath = join(outDir, 'lib.config.ts');
|
|
128
|
+
writeFileSync(outPath, render(), 'utf-8');
|
|
129
|
+
console.log(
|
|
130
|
+
`merge-lib-config: 已合并 ${Object.keys(mergedResolves).length} 个 resolve / ${mergedModules.length} 个 module -> ${outPath}`
|
|
131
|
+
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createRouter,
|
|
1
|
+
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
|
|
2
2
|
import { routes } from '@common/routes';
|
|
3
3
|
|
|
4
4
|
export const constantRoutes: RouteRecordRaw[] = [
|
|
@@ -10,7 +10,7 @@ export const constantRoutes: RouteRecordRaw[] = [
|
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
const router = createRouter({
|
|
13
|
-
history:
|
|
13
|
+
history: createWebHashHistory(),
|
|
14
14
|
routes: constantRoutes
|
|
15
15
|
})
|
|
16
16
|
|