@infly/vue2-vite 1.0.0
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/LICENSE +15 -0
- package/README.md +307 -0
- package/bin/infly-vue2-vite.mjs +12 -0
- package/bin/vue-cli-service.mjs +135 -0
- package/package.json +71 -0
- package/src/cli/arguments.mjs +197 -0
- package/src/cli/node-version.mjs +46 -0
- package/src/cli/run.mjs +122 -0
- package/src/compat/assets.mjs +165 -0
- package/src/compat/commonjs.mjs +93 -0
- package/src/compat/empty-stub.mjs +58 -0
- package/src/compat/html.mjs +244 -0
- package/src/compat/import-interop.mjs +200 -0
- package/src/compat/jsx.mjs +142 -0
- package/src/compat/mock.mjs +125 -0
- package/src/compat/require-context.mjs +157 -0
- package/src/compat/router.mjs +62 -0
- package/src/compat/sass-export.mjs +112 -0
- package/src/compat/sass-importer.mjs +30 -0
- package/src/compat/svg-icons.mjs +35 -0
- package/src/config/discover.mjs +261 -0
- package/src/config/env.mjs +148 -0
- package/src/config/merge.mjs +65 -0
- package/src/config/project-config.mjs +87 -0
- package/src/config/registered.mjs +152 -0
- package/src/config/validation.mjs +122 -0
- package/src/config/vue-cli-reader.mjs +207 -0
- package/src/factory/build-policy.mjs +39 -0
- package/src/factory/create-vite-config.mjs +648 -0
- package/src/factory/manual-chunks.mjs +55 -0
- package/src/factory/output-names.mjs +62 -0
- package/src/index.mjs +55 -0
- package/src/runner/build.mjs +43 -0
- package/src/runner/serve.mjs +44 -0
- package/src/runner/signals.mjs +29 -0
- package/src/runner/test.mjs +190 -0
- package/src/runner/workspace.cjs +346 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Infly
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# @infly/vue2-vite
|
|
2
|
+
|
|
3
|
+
当前稳定版本:`1.0.0`。1.0 稳定化保持公开入口、CLI 参数、`vue-cli-service` 兼容命令和运行行为不变。
|
|
4
|
+
|
|
5
|
+
Vue 2.7 项目专用的 Vite 7 构建适配器。安装一个包,获得两种入口:
|
|
6
|
+
|
|
7
|
+
- **独立 CLI**:`infly-vue2-vite serve` / `infly-vue2-vite build` / `infly-vue2-vite test`
|
|
8
|
+
- **`vue-cli-service` 薄分发器**:`vue-cli-service serve --infly-vite`(兼容旧命令习惯),`vue-cli-service test:unit` 转交 vitest
|
|
9
|
+
|
|
10
|
+
两种方式都只需安装 `@infly/vue2-vite`,无需额外依赖。
|
|
11
|
+
包括 mock 服务器转译所需的 Babel 能力,也由本包直接声明和解析。
|
|
12
|
+
|
|
13
|
+
## 安装
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add -D @infly/vue2-vite
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 两种使用方式
|
|
20
|
+
|
|
21
|
+
### 方式 1:独立 CLI(推荐)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# 开发服务器
|
|
25
|
+
pnpm exec infly-vue2-vite serve
|
|
26
|
+
pnpm exec infly-vue2-vite serve --port 9528
|
|
27
|
+
pnpm exec infly-vue2-vite serve --host localhost # 仅本机访问
|
|
28
|
+
|
|
29
|
+
# 生产构建
|
|
30
|
+
pnpm exec infly-vue2-vite build
|
|
31
|
+
pnpm exec infly-vue2-vite build --mode staging
|
|
32
|
+
pnpm exec infly-vue2-vite build --mode release --target MER
|
|
33
|
+
|
|
34
|
+
# 单元测试(vitest,jest API 兼容)
|
|
35
|
+
pnpm exec infly-vue2-vite test
|
|
36
|
+
pnpm exec infly-vue2-vite test --watch
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
独立 CLI 的开发服务器默认监听 `0.0.0.0`,允许通过局域网地址访问;存在多个网卡时,
|
|
40
|
+
启动日志只展示 Vite 返回的第一个 `Network` 地址,但服务仍监听所有网卡。
|
|
41
|
+
从子项目目录启动时会向上查找最近的 `pnpm-workspace.yaml`,并将 workspace 根目录的
|
|
42
|
+
`node_modules` 加入 Vite 文件访问范围,以支持 pnpm 根依赖中的字体等静态资源。
|
|
43
|
+
|
|
44
|
+
所有 Vite 构建模式只输出面向 Vite 7 Baseline Widely Available 浏览器的现代 ESM,不生成 SystemJS、`nomodule` 或旧浏览器 polyfill;Webpack 兼容策略由原 Vue CLI 工具链独立维护。
|
|
45
|
+
|
|
46
|
+
`package.json` 脚本:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"scripts": {
|
|
51
|
+
"dev": "infly-vue2-vite serve",
|
|
52
|
+
"dev:vite": "infly-vue2-vite serve --open",
|
|
53
|
+
"build:stage": "infly-vue2-vite build --mode staging",
|
|
54
|
+
"build:prod": "infly-vue2-vite build --mode production",
|
|
55
|
+
"build:release": "infly-vue2-vite build --mode release"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 方式 2:vue-cli-service 薄分发器
|
|
61
|
+
|
|
62
|
+
安装 `@infly/vue2-vite` 后自动获得 `vue-cli-service` 命令。根据 `@vue/cli-service` 是否可用自动选择模式:
|
|
63
|
+
|
|
64
|
+
- **Vite 工具链模式**(`@vue/cli-service` 不可用):`vue-cli-service` 默认走 Vite,`--infly-vite` 可选。
|
|
65
|
+
- **Webpack 共存模式**(`@vue/cli-service` 可用):不加 flag 走 Webpack,加 `--infly-vite` 走 Vite。
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Vite 工具链模式(默认即 Vite,--infly-vite 可选)
|
|
69
|
+
vue-cli-service serve
|
|
70
|
+
vue-cli-service build --mode staging
|
|
71
|
+
|
|
72
|
+
# Webpack 共存模式(默认 Webpack,加 flag 切换)
|
|
73
|
+
vue-cli-service serve # → Webpack
|
|
74
|
+
vue-cli-service serve --infly-vite # → Vite
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`package.json` 脚本(Vite 工具链模式):
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"scripts": {
|
|
82
|
+
"dev": "vue-cli-service serve",
|
|
83
|
+
"build:stage": "vue-cli-service build --mode staging",
|
|
84
|
+
"build:prod": "vue-cli-service build --mode production"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
> **注意**:Vite 工具链模式下 `.pnpmfile.cjs` 会裁剪 webpack 构建依赖(含 `@vue/cli-service`),薄分发器检测到缺失后自动默认 Vite,无需 `--infly-vite`。
|
|
90
|
+
|
|
91
|
+
### 薄分发器行为矩阵
|
|
92
|
+
|
|
93
|
+
**Vite 工具链模式(`@vue/cli-service` 不可用):**
|
|
94
|
+
|
|
95
|
+
| 命令 | 实际执行的构建器 |
|
|
96
|
+
|------|-----------------|
|
|
97
|
+
| `vue-cli-service serve` | `infly-vue2-vite` → Vite dev server |
|
|
98
|
+
| `vue-cli-service build` | `infly-vue2-vite` → Vite production build |
|
|
99
|
+
| `vue-cli-service serve --infly-vite` | `infly-vue2-vite` → Vite dev server(flag 可选) |
|
|
100
|
+
| `vue-cli-service test:unit` | `infly-vue2-vite test` → vitest run(jest API 兼容) |
|
|
101
|
+
|
|
102
|
+
**Webpack 共存模式(`@vue/cli-service` 可用):**
|
|
103
|
+
|
|
104
|
+
| 命令 | 实际执行的构建器 |
|
|
105
|
+
|------|-----------------|
|
|
106
|
+
| `vue-cli-service serve` | `@vue/cli-service` → Webpack dev server |
|
|
107
|
+
| `vue-cli-service build` | `@vue/cli-service` → Webpack production build |
|
|
108
|
+
| `vue-cli-service serve --infly-vite` | `infly-vue2-vite` → Vite dev server |
|
|
109
|
+
| `vue-cli-service build --infly-vite` | `infly-vue2-vite` → Vite production build |
|
|
110
|
+
| `vue-cli-service test:unit` | `@vue/cli-service` → Jest(Webpack) |
|
|
111
|
+
| `vue-cli-service test:unit --infly-vite` | `infly-vue2-vite test` → vitest run |
|
|
112
|
+
|
|
113
|
+
## 配置
|
|
114
|
+
|
|
115
|
+
### 优先级(从低到高)
|
|
116
|
+
|
|
117
|
+
1. `@infly/vue2-vite` 安全默认值
|
|
118
|
+
2. 项目 `vue.config.js` 中可自动转换的标准字段
|
|
119
|
+
3. `package.json` 的 `inflyVite` 字段
|
|
120
|
+
4. `infly.vite.config.js` / `.cjs` / `.mjs`(三选一)
|
|
121
|
+
5. CLI 参数
|
|
122
|
+
|
|
123
|
+
### package.json 配置
|
|
124
|
+
|
|
125
|
+
适合放稳定的默认值:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"inflyVite": {
|
|
130
|
+
"defaultTarget": "DEFAULT",
|
|
131
|
+
"mainEntry": "src/main.js",
|
|
132
|
+
"htmlTemplate": "public/index.html",
|
|
133
|
+
"strictCompatibility": true
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### infly.vite.config.js 示例
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
const path = require("node:path");
|
|
142
|
+
|
|
143
|
+
module.exports = function createInflyViteConfig(context) {
|
|
144
|
+
// context: { command, mode, target, projectRoot, isBuild, isServe }
|
|
145
|
+
|
|
146
|
+
const targetConfigs = {
|
|
147
|
+
DEFAULT: { port: 9528, outputDir: "../dist/ea", title: "邮惠权益平台", theme: "default" },
|
|
148
|
+
MER: { port: 9530, outputDir: "../dist/mer", title: "邮惠权益平台商家端", theme: "mer" },
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const cfg = targetConfigs[context.target];
|
|
152
|
+
if (!cfg) throw new Error(`未知 target: ${context.target}`);
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
outputDir: cfg.outputDir,
|
|
156
|
+
server: { port: cfg.port },
|
|
157
|
+
html: { title: cfg.title, favicon: "public/favicon.ico" },
|
|
158
|
+
css: {
|
|
159
|
+
additionalData: `@import "@/styles/mixin.scss";\n@import "@/styles/theme.${cfg.theme}.scss";`,
|
|
160
|
+
},
|
|
161
|
+
resolve: { alias: { "@": path.resolve(__dirname, "src") } },
|
|
162
|
+
mock: { entry: "mock/mock-server.js", enabled: context.command === "serve" },
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### vue.config.js 自动转换字段
|
|
168
|
+
|
|
169
|
+
| Vue CLI 字段 | Vite 映射 | 条件 |
|
|
170
|
+
|-------------|----------|------|
|
|
171
|
+
| `publicPath` | `base` | 字符串 |
|
|
172
|
+
| `outputDir` | `build.outDir` | 字符串 |
|
|
173
|
+
| `assetsDir` | `build.assetsDir` | 字符串 |
|
|
174
|
+
| `productionSourceMap` | `build.sourcemap` | 布尔值 |
|
|
175
|
+
| `devServer.port` | `server.port` | 数字 |
|
|
176
|
+
| `devServer.proxy` | `server.proxy` | 对象 |
|
|
177
|
+
| `css.loaderOptions.scss.additionalData` | `css.preprocessorOptions.scss.additionalData` | 字符串 |
|
|
178
|
+
| `configureWebpack.resolve.alias` | `resolve.alias` | 对象形式 |
|
|
179
|
+
| `configureWebpack.name` | HTML title | 字符串 |
|
|
180
|
+
|
|
181
|
+
对象形式 `configureWebpack.resolve.alias` 中的绝对源码目录也会进入兼容转换范围;
|
|
182
|
+
因此单项目启动时,通过别名加载的跨应用源码若包含静态 `require.context`,仍会转换为
|
|
183
|
+
`import.meta.glob`,无需在子模块中增加专用 Vite 配置。
|
|
184
|
+
|
|
185
|
+
以下字段不能自动转换:
|
|
186
|
+
- `chainWebpack`:严格兼容模式下会失败;其行为由内置默认能力覆盖(SVG sprite、whitespace、资源内联、分包、drop console 等),非严格模式不再产生诊断
|
|
187
|
+
- 函数形式 `configureWebpack`:无法猜测转换
|
|
188
|
+
- 任意 webpack plugin/loader:需通过显式配置提供等价 Vite 插件
|
|
189
|
+
|
|
190
|
+
### 缺失具名导出兼容
|
|
191
|
+
|
|
192
|
+
应用源码中的相对路径和 `@/` JavaScript 模块若缺少被导入的具名导出,兼容层会输出
|
|
193
|
+
Vite warning,并将该导入降级为 namespace 解构;缺失值为 `undefined`,不会阻断开发服务器
|
|
194
|
+
或生产构建。第三方依赖、TypeScript、Vue SFC 以及包含未知 `export *` 的桶文件不做降级,
|
|
195
|
+
仍保留 Vite 原生错误,以免隐藏真实依赖契约问题。
|
|
196
|
+
|
|
197
|
+
## Node 要求
|
|
198
|
+
|
|
199
|
+
Vite 7 要求 Node `^20.19.0` 或 `>=22.12.0`。推荐 Node `22.23.1`。
|
|
200
|
+
|
|
201
|
+
版本不满足时,CLI 在加载 Vite 之前退出并显示:
|
|
202
|
+
|
|
203
|
+
```text
|
|
204
|
+
@infly/vue2-vite 当前 Node 为 18.20.8;Vite 7 要求 Node ^20.19.0 或 >=22.12.0。
|
|
205
|
+
请切换到 Node 22.23.1 后重试。默认 Webpack 命令未受影响。
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## 退出码
|
|
209
|
+
|
|
210
|
+
| 状态 | 退出码 |
|
|
211
|
+
|------|--------|
|
|
212
|
+
| 成功 | 0 |
|
|
213
|
+
| 参数错误 | 2 |
|
|
214
|
+
| Node 版本不满足 | 3 |
|
|
215
|
+
| 配置错误 | 4 |
|
|
216
|
+
| 兼容检查失败 | 5 |
|
|
217
|
+
| Vite serve 启动失败 | 10 |
|
|
218
|
+
| Vite build 失败 | 11 |
|
|
219
|
+
|
|
220
|
+
## Node API
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
import {
|
|
224
|
+
build,
|
|
225
|
+
createViteConfig,
|
|
226
|
+
discoverConfig,
|
|
227
|
+
extractAdditionalVueConfigInfo,
|
|
228
|
+
loadVueCliConfig,
|
|
229
|
+
serve,
|
|
230
|
+
} from '@infly/vue2-vite';
|
|
231
|
+
|
|
232
|
+
// 加载项目配置
|
|
233
|
+
const { config } = await discoverConfig({
|
|
234
|
+
command: 'build',
|
|
235
|
+
mode: 'production',
|
|
236
|
+
projectRoot: process.cwd(),
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// 单独检查旧 Vue CLI 配置;只返回可转换字段和诊断,不修改调用方配置
|
|
240
|
+
const { vueConfig, warnings } = loadVueCliConfig(process.cwd(), 'production');
|
|
241
|
+
const legacyInfo = extractAdditionalVueConfigInfo(process.cwd());
|
|
242
|
+
|
|
243
|
+
// 生成 Vite UserConfig
|
|
244
|
+
const viteConfig = createViteConfig(config);
|
|
245
|
+
|
|
246
|
+
// 执行构建
|
|
247
|
+
await build(viteConfig);
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Monorepo 注册式配置
|
|
251
|
+
|
|
252
|
+
Monorepo 可以保留自己的应用清单和部署元数据,通过注册式 API 注入公共工厂:
|
|
253
|
+
|
|
254
|
+
```js
|
|
255
|
+
const {
|
|
256
|
+
createRegisteredViteConfig,
|
|
257
|
+
} = require('@infly/vue2-vite/registered');
|
|
258
|
+
|
|
259
|
+
module.exports = ({ command, mode }) => createRegisteredViteConfig(app, {
|
|
260
|
+
command: command === 'serve' ? 'serve' : 'build',
|
|
261
|
+
mode,
|
|
262
|
+
target: process.env.VUE_APP_PLATFORM,
|
|
263
|
+
rootDir: monorepoRoot,
|
|
264
|
+
appSourcePaths: registeredAppPaths,
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
批量 workspace 入口使用 `@infly/vue2-vite/workspace` 的
|
|
269
|
+
`createWorkspaceRunner(dependencies)`,显式注入 `registry`、`getTargetConfig`、
|
|
270
|
+
`createConfigPath` 和 `defaultRootDir`。公共包不会读取调用方的 `configs/`、
|
|
271
|
+
`scripts/` 或应用清单。runner 会为每个 dev/build 子进程注入
|
|
272
|
+
`INFLY_VITE_APP_ID` 和从应用 `package.json` 读取的 `INFLY_VITE_APP_VERSION`,
|
|
273
|
+
因此多个注册应用可以共用同一个调用方 Vite 配置入口,并在 HTML 中展示各自版本。
|
|
274
|
+
模板已有 `window.BUILD_INFO` 时兼容层不会重复注入;模板没有时才创建该对象。
|
|
275
|
+
|
|
276
|
+
公共工厂使用包含运行时编译器的 `vue/dist/vue.esm.js`,用于兼容 Vue 2 项目中的
|
|
277
|
+
`Vue.extend({ template })`。默认分包会为 `@infly/ui` 与 `@infly/libs`(含其
|
|
278
|
+
`@infly/ts-libs` 权威实现)生成独立的
|
|
279
|
+
`vendor-infly-ui`、`vendor-infly-libs` 产物;其他依赖继续交给 Rollup 按模块图拆分。
|
|
280
|
+
|
|
281
|
+
## 回滚
|
|
282
|
+
|
|
283
|
+
从脚本删除 `--infly-vite`,立即恢复原 Webpack:
|
|
284
|
+
|
|
285
|
+
```diff
|
|
286
|
+
- "dev": "vue-cli-service serve --infly-vite"
|
|
287
|
+
+ "dev": "vue-cli-service serve"
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
或删除 `@infly/vue2-vite` 依赖:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
pnpm remove @infly/vue2-vite
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
默认 Webpack 始终存在(`@vue/cli-service` 由项目自行管理),回滚不需要重新安装整个项目。
|
|
297
|
+
|
|
298
|
+
## 与 @infly/libs 的关系
|
|
299
|
+
|
|
300
|
+
- `@infly/vue2-vite` **不依赖** `@infly/libs`
|
|
301
|
+
- `@infly/libs` 提供一个可选的薄分发器版本,供 admin-monorepo 内部使用
|
|
302
|
+
- 独立项目直接安装 `@infly/vue2-vite` 即可获得完整能力(含 `vue-cli-service` 薄分发器)
|
|
303
|
+
- Monorepo 注册式 API 只消费调用方注入的数据,不包含任何具体应用、客户或部署目标
|
|
304
|
+
|
|
305
|
+
## 许可
|
|
306
|
+
|
|
307
|
+
ISC
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* vue-cli-service 薄分发器(@infly/vue2-vite 内建版本)
|
|
5
|
+
*
|
|
6
|
+
* 使已习惯 vue-cli-service 命令的项目只需加 --infly-vite 即可切换到 Vite。
|
|
7
|
+
* 与 @infly/libs 版本不同:此版本是纯项目本地实现,无 monorepo 根检测。
|
|
8
|
+
*
|
|
9
|
+
* 行为矩阵(Vite 工具链模式,@vue/cli-service 不可用):
|
|
10
|
+
* vue-cli-service serve → Vite dev server(默认)
|
|
11
|
+
* vue-cli-service build → Vite build(默认)
|
|
12
|
+
* vue-cli-service serve --infly-vite → Vite dev server(标志可选)
|
|
13
|
+
* vue-cli-service test:unit → vitest run(转交 infly-vue2-vite test)
|
|
14
|
+
*
|
|
15
|
+
* 行为矩阵(Webpack 共存模式,@vue/cli-service 可用):
|
|
16
|
+
* vue-cli-service serve → 原始 @vue/cli-service(Webpack)
|
|
17
|
+
* vue-cli-service build → 原始 @vue/cli-service(Webpack)
|
|
18
|
+
* vue-cli-service serve --infly-vite → infly-vue2-vite serve(Vite)
|
|
19
|
+
* vue-cli-service build --infly-vite → infly-vue2-vite build(Vite)
|
|
20
|
+
* vue-cli-service test:unit --infly-vite → vitest run(转交 infly-vue2-vite test)
|
|
21
|
+
* Vite 构建失败 → 不回退 Webpack
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import fs from 'node:fs';
|
|
25
|
+
import path from 'node:path';
|
|
26
|
+
import { spawn } from 'node:child_process';
|
|
27
|
+
import { createRequire } from 'node:module';
|
|
28
|
+
import { fileURLToPath } from 'node:url';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 从参数中检测并消费 --infly-vite
|
|
32
|
+
*/
|
|
33
|
+
function parseFlags(argv) {
|
|
34
|
+
let hasInflyVite = false;
|
|
35
|
+
const remaining = [];
|
|
36
|
+
|
|
37
|
+
for (const arg of argv) {
|
|
38
|
+
if (arg === '--infly-vite') {
|
|
39
|
+
hasInflyVite = true;
|
|
40
|
+
} else {
|
|
41
|
+
remaining.push(arg);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return { hasInflyVite, remaining };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 生成子进程并转发信号
|
|
50
|
+
*/
|
|
51
|
+
function spawnForwarded(executable, args, options) {
|
|
52
|
+
const child = spawn(executable, args, { ...options, stdio: 'inherit' });
|
|
53
|
+
|
|
54
|
+
['SIGINT', 'SIGTERM'].forEach((sig) => {
|
|
55
|
+
process.once(sig, () => child.kill(sig));
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
child.once('error', (err) => {
|
|
59
|
+
console.error(err.message);
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
child.once('exit', (code, signal) => {
|
|
64
|
+
process.exitCode = typeof code === 'number' ? code : signal ? 1 : 0;
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return child;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 启动 Vite(通过 infly-vue2-vite CLI)
|
|
72
|
+
*/
|
|
73
|
+
function spawnVite(args, cwd) {
|
|
74
|
+
const selfDir = path.dirname(fileURLToPath(import.meta.url));
|
|
75
|
+
const viteCli = path.resolve(selfDir, 'infly-vue2-vite.mjs');
|
|
76
|
+
|
|
77
|
+
if (!fs.existsSync(viteCli)) {
|
|
78
|
+
console.error(
|
|
79
|
+
'[vue-cli-service] 找不到 infly-vue2-vite CLI 入口。请确认 @infly/vue2-vite 安装完整。'
|
|
80
|
+
);
|
|
81
|
+
process.exitCode = 1;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return spawnForwarded(process.execPath, [viteCli, ...args], {
|
|
86
|
+
cwd,
|
|
87
|
+
env: process.env,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 检测 @vue/cli-service 是否可用
|
|
93
|
+
* Vite 工具链模式下 .pnpmfile.cjs 会裁剪 webpack 依赖,导致解析失败 → 默认走 Vite
|
|
94
|
+
*/
|
|
95
|
+
function resolveVueCliService(cwd) {
|
|
96
|
+
try {
|
|
97
|
+
return createRequire(path.join(cwd, 'package.json'))
|
|
98
|
+
.resolve('@vue/cli-service/bin/vue-cli-service.js');
|
|
99
|
+
} catch (_) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function run(argv = process.argv.slice(2), cwd = process.cwd()) {
|
|
105
|
+
const { hasInflyVite, remaining } = parseFlags(argv);
|
|
106
|
+
const vueCliBin = resolveVueCliService(cwd);
|
|
107
|
+
|
|
108
|
+
// Vite 工具链模式:@vue/cli-service 不可用,默认走 Vite(--infly-vite 可选)
|
|
109
|
+
if (!vueCliBin) {
|
|
110
|
+
if (remaining[0] === 'test:unit') {
|
|
111
|
+
// test:unit → vitest(jest API 由 vitest globals 兼容)
|
|
112
|
+
return spawnVite(['test', ...remaining.slice(1)], cwd);
|
|
113
|
+
}
|
|
114
|
+
return spawnVite(remaining, cwd);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Webpack 共存模式:默认 Webpack,加 --infly-vite 切换 Vite
|
|
118
|
+
if (!hasInflyVite) {
|
|
119
|
+
return spawnForwarded(process.execPath, [vueCliBin, ...remaining], {
|
|
120
|
+
cwd,
|
|
121
|
+
env: process.env,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 有 --infly-vite → 使用 Vite
|
|
126
|
+
|
|
127
|
+
// test:unit → vitest(jest API 由 vitest globals 兼容)
|
|
128
|
+
if (remaining[0] === 'test:unit') {
|
|
129
|
+
return spawnVite(['test', ...remaining.slice(1)], cwd);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return spawnVite(remaining, cwd);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
run();
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@infly/vue2-vite",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Explicit opt-in Vite 7 build adapter for Vue 2.7 projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"infly-vue2-vite": "./bin/infly-vue2-vite.mjs",
|
|
11
|
+
"vue-cli-service": "./bin/vue-cli-service.mjs"
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": "./src/index.mjs",
|
|
15
|
+
"./config": "./src/config/project-config.mjs",
|
|
16
|
+
"./registered": "./src/config/registered.mjs",
|
|
17
|
+
"./workspace": "./src/runner/workspace.cjs",
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"bin/",
|
|
22
|
+
"src/",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"eslint": "^9.0.0",
|
|
31
|
+
"globals": "^15.0.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"vue": "^2.7.16",
|
|
35
|
+
"@vue/test-utils": "^1.3.6"
|
|
36
|
+
},
|
|
37
|
+
"peerDependenciesMeta": {
|
|
38
|
+
"@vue/test-utils": {
|
|
39
|
+
"optional": true
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@babel/core": "^7.23.3",
|
|
44
|
+
"@babel/preset-env": "^7.23.3",
|
|
45
|
+
"@babel/register": "^7.22.15",
|
|
46
|
+
"@vitejs/plugin-vue2": "2.3.4",
|
|
47
|
+
"@vue/babel-preset-jsx": "1.4.0",
|
|
48
|
+
"autoprefixer": "10.4.16",
|
|
49
|
+
"body-parser": "^2.3.0",
|
|
50
|
+
"chalk": "4.1.2",
|
|
51
|
+
"chokidar": "3.6.0",
|
|
52
|
+
"express": "4.21.2",
|
|
53
|
+
"jsdom": "^28.0.0",
|
|
54
|
+
"path-browserify": "1.0.1",
|
|
55
|
+
"postcss": "8.4.31",
|
|
56
|
+
"sass": "^1.70.0",
|
|
57
|
+
"vite": "7.3.6",
|
|
58
|
+
"vite-plugin-svg-icons-ng": "1.9.2",
|
|
59
|
+
"vitest": "^4.0.0"
|
|
60
|
+
},
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "https://gitee.com/gdinfly_1/admin-monorepo.git"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"test": "node --test test/*.test.mjs",
|
|
67
|
+
"lint": "eslint .",
|
|
68
|
+
"check:pack": "pnpm pack --dry-run",
|
|
69
|
+
"publishPkg": "pnpm publish --access=public --registry=https://registry.npmjs.org/ --no-git-checks"
|
|
70
|
+
}
|
|
71
|
+
}
|