Compare commits

..
7 Commits
Author SHA1 Message Date
xrain 13c836b4ab 修改退出登录没带TOKEn
Publish to npm / publish (push) Failing after 14s
2026-05-03 23:11:55 +08:00
xrain 88be4210aa 修正文档 2026-04-26 10:44:40 +08:00
xrain 4257f72799 fix ci
Publish to npm / publish (push) Failing after 8s
2026-04-23 21:39:57 +08:00
xrain 46257ecf4a fix version 2026-04-23 21:39:38 +08:00
xrain a2f57bc419 增加了AppVersion
Publish to npm / publish (push) Failing after 12s
2026-04-23 20:16:38 +08:00
xrain fe77c0ee1a 修正了业务错误报错
Publish to npm / publish (push) Failing after 12s
2026-04-22 22:08:35 +08:00
xrain 98c46f4a7b 修改了环境变量
Publish to npm / publish (push) Failing after 11s
2026-04-08 02:58:50 +08:00
8 changed files with 970 additions and 738 deletions
-2
View File
@@ -31,8 +31,6 @@ jobs:
run: npm ci
- name: Build
env:
SimApiVersion: ${{ github.ref_name }}
run: npm run build
- name: Publish to npm
-166
View File
@@ -1,166 +0,0 @@
# @simcu/simapi — AI 开发指南
> 面向 AI Agent 的代码结构说明,帮助理解、修改和扩展本库。
---
## 项目结构
```
simapi-vue/
├── src/
│ ├── types.ts # 类型定义,全部导出
│ ├── simapi.core.ts # 核心类 SimApiCore,零框架依赖
│ └── simapi.pinia.ts # Pinia StoreVue3 适配层
├── dist/ # 构建产物
├── package.json # exports: "." → core, "/pinia" → vue
├── vite.config.ts # 统一构建配置,生成 .mjs 和 .cjs
└── tsconfig.build.json # tsc 生成类型声明
```
---
## 核心类型(types.ts
```typescript
SimApiBaseResponse<T> // 标准响应 { code, message, data? }
SimApiOptions // configure() 入参 { debug?, auth?, api? }
SimApiAuthConfig // auth: { token_name, check_url, logout_url, login_url }
SimApiApiConfig // api: { endpoints, defaultEndpoint, businessCallback, responseCallback, timeout? }
SimApiBusinessCallback // { [code]: (data) => void },支持数字码或 'common'
```
---
## SimApiCoresimapi.core.ts
**职责**:纯 TS HTTP 客户端,基于原生 fetch API,不依赖任何框架。
**关键设计**
- **零依赖**:使用原生 fetch,无 axios 或其他 HTTP 库
- **无 Cookie**:所有请求使用 `credentials: 'omit'`,避免 CORS 问题
- **Token 传递**:通过请求头 `Token` 传递认证信息
- **超时控制**:通过 `fetchWithTimeout` 辅助函数实现
- `query()` 抛出异常的只有网络/HTTP 错误,业务错误码通过回调处理
- `isLoggedIn` 是 getter,基于 localStorage 中的 token 判断
- **版本号**`getVersion()` 返回的版本信息中,`uiSimApi` 由构建时注入的 `SimApiVersion` 填充,`uiApp` 由调用方的 `AppVersion` 填充(未注入时为 `0.0.0-develop`
**修改建议**
- 改请求方法(GET/PUT/DELETE):在 `fetchPost()` 内新增 `method` 参数分支,或新增 `fetchGet()`/`fetchPut()` 方法
- 改 Token 存储:替换 `localStorage``sessionStorage` 或内存变量,修改 `getToken()`/`setToken()`/`removeToken()`
- 改登录/登出逻辑:修改 `login()`/`logout()` 方法
- 改超时处理:修改 `fetchWithTimeout()` 函数
- **版本管理**:版本号通过 `declare const` 声明常量,构建时通过 Vite 的 `define` 注入。未指定时默认为 `0.0.0-develop`
**autoInit 设计约束**
- 仅读取 `window.simapi` 的顶级字段:`endpoints``defaultEndpoint``debug`
- 业务回调(`businessCallback`/`responseCallback`)不支持从 window 读取,必须在代码中通过 `setBusinessCallback` 注册
---
## Pinia Storesimapi.pinia.ts
**职责**Vue3 适配层,SimApiCore 的纯代理,不维护任何独立状态。
**关键设计**
- **无独立状态**:state 中只有一个 `_core` 实例,不维护 `debug``token` 等独立数据
- **单例 Core**:在 store state 中实例化 `SimApiCore`,整个应用共享一个实例
- **纯代理映射**:所有 getters 直接映射到 `this._core` 的属性,所有 actions 直接调用 `this._core` 的方法
- **响应式**:通过 Pinia 的响应式系统,当 core 状态变化时自动更新
**使用方式**
```typescript
// 任意组件
import { useSimApi } from '@simcu/simapi'
const api = useSimApi()
// 初始化(二选一)
// 方式一:从 window.simapi 读取
api.autoInit()
// 方式二:直接传入配置
api.configure({
api: { endpoints: { default: 'https://api.example.com' } },
})
// 所有方法与 SimApiCore 完全一致
await api.query('/users/list', { page: 1 })
```
---
## 构建流程
```
npm run build
→ vite build 输出 dist/index.mjs / index.cjs / pinia.mjs / pinia.cjs
→ tsc -p tsconfig.build.json 输出 *.d.ts 类型声明
```
**版本号注入:**
版本号通过 `vite.config.ts``define` 配置注入,从 npm config 读取:
```typescript
define: {
'SimApiVersion': JSON.stringify(process.env.npm_config_SimApiVersion || '0.0.0-develop'),
}
```
**本地构建示例:**
```bash
# 通过环境变量
# Windows PowerShell
$env:npm_config_SimApiVersion='1.0.0'; npm run build
# Linux/Mac
npm_config_SimApiVersion=1.0.0 npm run build
```
**GitHub Actions 自动发布:**
```yaml
env:
SimApiVersion: ${{ github.ref_name }}
run: npm run build
```
**dist 输出是平铺的**core 和 pinia 的编译产物全部在同一目录:
```
dist/
├── index.mjs # core ESM
├── index.cjs # core CJS
├── pinia.mjs # pinia ESM
├── pinia.cjs # pinia CJS
├── simapi.core.d.ts
├── simapi.pinia.d.ts
└── types.d.ts
```
---
## package.json exports
```json
".": { "import": "./dist/index.mjs", "types": "./dist/simapi.core.d.ts" }
"./pinia": { "import": "./dist/pinia.mjs", "types": "./dist/simapi.pinia.d.ts" }
```
---
## 注意事项
- Core 默认 `debug: true`,生产环境需手动 `configure({ debug: false })`
- `query()` 返回 `Promise<SimApiBaseResponse<T>>`code !== 200 时不 reject,通过 `businessCallback` 处理
- `login()` 成功后将 `result.data` 存入 localStorage
- **无 Cookie**:所有请求不发送 CookieToken 通过请求头传递
- **零依赖**:不需要安装 axios,使用原生 fetch
- 删除了 Angular 支持,如需恢复参考 git 历史
- **版本号管理**:使用 `declare const` + Vite `define` 注入
- **AppVersion** 不注入,留给调用方自己管理
+672 -309
View File
File diff suppressed because it is too large Load Diff
+18
View File
@@ -12,6 +12,7 @@
"tslib": "^2.3.0"
},
"devDependencies": {
"@types/node": "^25.6.0",
"concurrently": "^9.2.1",
"pinia": "^2.2.0",
"typescript": "~5.9.3",
@@ -433,6 +434,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "25.6.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz",
"integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.19.0"
}
},
"node_modules/@vue/compiler-core": {
"version": "3.5.32",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.32.tgz",
@@ -1004,6 +1015,13 @@
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "7.19.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz",
"integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==",
"dev": true,
"license": "MIT"
},
"node_modules/vite": {
"version": "5.4.21",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
+1
View File
@@ -42,6 +42,7 @@
"tslib": "^2.3.0"
},
"devDependencies": {
"@types/node": "^25.6.0",
"concurrently": "^9.2.1",
"pinia": "^2.2.0",
"typescript": "~5.9.3",
+273 -255
View File
@@ -11,300 +11,318 @@
*/
import {
type SimApiVersions,
type SimApiAuthConfig,
type SimApiApiConfig,
type SimApiOptions,
type SimApiBaseResponse,
type SimApiVersions,
type SimApiAuthConfig,
type SimApiApiConfig,
type SimApiOptions,
type SimApiBaseResponse,
} from './types'
export type {
SimApiVersions,
SimApiAuthConfig,
SimApiApiConfig,
SimApiOptions,
SimApiBaseResponse,
SimApiVersions,
SimApiAuthConfig,
SimApiApiConfig,
SimApiOptions,
SimApiBaseResponse,
} from './types'
declare const SimApiVersion: string;
declare const AppVersion: string;
// ── Helper: Fetch with Timeout ────────────────────────────────────────
function fetchWithTimeout(
url: string,
options: RequestInit,
timeout: number = 10000
url: string,
options: RequestInit,
timeout: number = 10000
): Promise<Response> {
return Promise.race([
fetch(url, options),
new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error(`Request timeout after ${timeout}ms`)), timeout)
),
])
return Promise.race([
fetch(url, options),
new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error(`Request timeout after ${timeout}ms`)), timeout)
),
])
}
// ── Helper: Fetch POST with JSON body ────────────────────────────────────
async function fetchPost<T = any>(
url: string,
body: any,
headers: Record<string, string>,
timeout: number
url: string,
body: any,
headers: Record<string, string>,
timeout: number
): Promise<SimApiBaseResponse<T>> {
const options: RequestInit = {
method: 'POST',
headers: headers as HeadersInit,
body: body instanceof FormData ? body : JSON.stringify(body),
credentials: 'omit', // 从不发送 Cookie
}
const response = await fetchWithTimeout(url, options, timeout)
if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
throw {
status: response.status,
statusText: response.statusText,
data: errorData,
message: `HTTP ${response.status}: ${response.statusText}`,
const options: RequestInit = {
method: 'POST',
headers: headers as HeadersInit,
body: body instanceof FormData ? body : JSON.stringify(body),
credentials: 'omit', // 从不发送 Cookie
}
}
return response.json()
const response = await fetchWithTimeout(url, options, timeout)
if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
throw {
status: response.status,
statusText: response.statusText,
data: errorData,
message: `HTTP ${response.status}: ${response.statusText}`,
}
}
return response.json()
}
// ── SimApiCore ────────────────────────────────────────
export class SimApiCore {
debug: boolean = true
auth: SimApiAuthConfig = {
token_name: 'simapi-auth-token',
check_url: '/auth/check',
logout_url: '/auth/logout',
login_url: '/auth/login',
}
api: SimApiApiConfig = {
endpoints: { default: '' },
defaultEndpoint: 'default',
businessCallback: {
401: () => localStorage.removeItem(this.auth.token_name),
common: () => {},
},
responseCallback: {
success: (response: any) => response,
error: (_err: any) => {},
},
timeout: 10000,
}
constructor(options?: SimApiOptions) {
if (options) {
this.configure(options)
debug: boolean = true
auth: SimApiAuthConfig = {
token_name: 'simapi-auth-token',
check_url: '/auth/check',
logout_url: '/auth/logout',
login_url: '/auth/login',
}
}
/**
* 从 window.simapi 读取配置并初始化
*
* 支持字段:endpoints, defaultEndpoint, debug
* 业务回调(businessCallback / responseCallback)需在代码中处理
*/
autoInit(): void {
const config = (window as any).simapi
if (!config) return
if (config.debug !== undefined) {
this.debug = config.debug
api: SimApiApiConfig = {
endpoints: {default: ''},
defaultEndpoint: 'default',
businessCallback: {
401: () => localStorage.removeItem(this.auth.token_name),
common: () => {
},
},
responseCallback: {
success: (response: any) => response,
error: (_err: any) => {
},
},
timeout: 10000,
}
if (config.endpoints) {
this.api.endpoints = { ...this.api.endpoints, ...config.endpoints }
}
if (config.defaultEndpoint) {
this.api.defaultEndpoint = config.defaultEndpoint
}
}
configure(options: SimApiOptions): void {
if (options.debug !== undefined) {
this.debug = options.debug
}
if (options.auth) {
this.auth = { ...this.auth, ...options.auth }
}
if (options.api) {
this.api = {
...this.api,
...options.api,
endpoints: { ...this.api.endpoints, ...(options.api.endpoints ?? {}) },
businessCallback: { ...this.api.businessCallback, ...(options.api.businessCallback ?? {}) },
responseCallback: { ...this.api.responseCallback, ...(options.api.responseCallback ?? {}) },
}
}
}
setEndpoints(endpoints: { [name: string]: string }): void {
this.api.endpoints = { ...this.api.endpoints, ...endpoints }
}
getEndpoint(name?: string): string {
return this.api.endpoints[name ?? this.api.defaultEndpoint] ?? ''
}
setBusinessCallback(code: number | string, callback: (data: any) => void): void {
this.api.businessCallback[code] = callback
}
getToken(): string {
return localStorage.getItem(this.auth.token_name) ?? ''
}
setToken(token: string): void {
localStorage.setItem(this.auth.token_name, token)
}
removeToken(): void {
localStorage.removeItem(this.auth.token_name)
}
get isLoggedIn(): boolean {
return !!localStorage.getItem(this.auth.token_name)
}
genS4(): string {
return (((1 + Math.random()) * 0x10000 * Date.parse(new Date().toString())) | 0)
.toString(16)
.substring(1)
}
/**
* 日志工具(仅在 debug 模式下输出)
*
* @example
* api.logDebug('用户登录', { id: 1, name: 'test' })
* api.logDebug('请求开始', uri, params)
*/
logDebug(...args: any[]): void {
if (!this.debug) return
console.log('[DEBUG]', ...args)
}
/**
* 获取版本信息
*
* @param endpointName - 指定从哪个 endpoint 获取版本,默认使用 default endpoint
* @returns 版本信息对象
*
* @example
* // 从默认 endpoint 获取
* const versions = await api.getVersion()
*
* // 从指定 endpoint 获取
* const versions = await api.getVersion('backup')
*/
async getVersion(endpointName?: string): Promise<SimApiVersions> {
const versions: SimApiVersions = {
uiApp: '0.0.0-develop',
uiSimApi: typeof SimApiVersion === 'undefined' ? "0.0.0-develop" : SimApiVersion,
apiApp: '0.0.0',
apiSimApi: '0.0.0',
apiAppFull: '0.0.0',
apiSimApiFull: '0.0.0',
};
try {
const resp = await this.query<any>('/versions', {}, endpointName)
if (resp?.data) {
const d = resp.data
versions.apiApp= d.App?.split('+')[0] ?? '0.0.0';
versions.apiSimApi= d.SimApi?.split('+')[0] ?? '0.0.0';
versions.apiAppFull= d.App ?? '0.0.0';
versions.apiSimApiFull= d.SimApi ?? '0.0.0';
if (this.debug) {
console.log(`UI主应用版本: ${versions.uiApp}\nUISimApi版本: ${versions.uiSimApi}\nAPI主应用版本: ${versions.apiApp}\nAPISimApi版本: ${versions.apiSimApi}`)
constructor(options?: SimApiOptions) {
if (options) {
this.configure(options)
}
return versions
}
} catch {
// 版本获取失败返回默认值
}
return versions;
}
async query<T = any>(
uri: string,
params: any = {},
endpointKey?: string,
extraHeaders?: Record<string, string>
): Promise<SimApiBaseResponse<T>> {
const headers: Record<string, string> = { ...extraHeaders, ...{} }
const queryId = this.genS4()
if (!(params instanceof FormData)) {
headers['Content-Type'] = 'application/json'
}
const token = this.getToken()
if (token) {
headers['Token'] = token
/**
* 从 window.simapi 读取配置并初始化
*
* 支持字段:endpoints, defaultEndpoint, debug
* 业务回调(businessCallback / responseCallback)需在代码中处理
*/
autoInit(): void {
const config = (window as any).simapi
if (!config) return
if (config.debug !== undefined) {
this.debug = config.debug
}
if (config.endpoints) {
this.api.endpoints = {...this.api.endpoints, ...config.endpoints}
}
if (config.defaultEndpoint) {
this.api.defaultEndpoint = config.defaultEndpoint
}
}
if (this.debug) {
headers['Query-Id'] = queryId
console.log('[REQUEST*]', queryId, '->', uri, 'AUTH:', localStorage.getItem(this.auth.token_name))
configure(options: SimApiOptions): void {
if (options.debug !== undefined) {
this.debug = options.debug
}
if (options.auth) {
this.auth = {...this.auth, ...options.auth}
}
if (options.api) {
this.api = {
...this.api,
...options.api,
endpoints: {...this.api.endpoints, ...(options.api.endpoints ?? {})},
businessCallback: {...this.api.businessCallback, ...(options.api.businessCallback ?? {})},
responseCallback: {...this.api.responseCallback, ...(options.api.responseCallback ?? {})},
}
}
}
const url = this.getEndpoint(endpointKey) + uri
try {
const respData = await fetchPost<T>(
url,
params,
headers,
this.api.timeout ?? 10000
)
if (this.debug) {
console.log('[RESPONSE]', queryId, '->', respData)
}
const processedData = this.api.responseCallback.success(respData) as SimApiBaseResponse<T>
// 业务回调处理
if (this.api.businessCallback.hasOwnProperty(processedData.code)) {
this.api.businessCallback[processedData.code](processedData)
} else if (this.api.businessCallback['common'] && processedData.code !== 200) {
this.api.businessCallback['common'](processedData)
}
// 直接返回,不再根据 code 抛出错误
return processedData
} catch (error) {
if (this.debug) {
console.log('[RESPONSE]', queryId, '->', error)
}
this.api.responseCallback.error(error)
throw error
setEndpoints(endpoints: { [name: string]: string }): void {
this.api.endpoints = {...this.api.endpoints, ...endpoints}
}
}
async login(request: Record<string, any>): Promise<SimApiBaseResponse<string>> {
const result = await this.query<string>(this.auth.login_url, request)
if (result?.data) {
this.setToken(result.data)
getEndpoint(name?: string): string {
return this.api.endpoints[name ?? this.api.defaultEndpoint] ?? ''
}
return result
}
async logout(url?: string | null): Promise<any> {
this.removeToken()
if (url !== null) {
return this.query(url ?? this.auth.logout_url).catch(() => true)
setBusinessCallback(code: number | string, callback: (data: any) => void): void {
this.api.businessCallback[code] = callback
}
return true
}
async checkLogin(url?: string | null): Promise<void> {
if (url !== null) {
await this.query(url ?? this.auth.check_url).catch(() => {})
} else if (this.getToken()) {
this.api.businessCallback[401]?.(null)
getToken(): string {
return localStorage.getItem(this.auth.token_name) ?? ''
}
setToken(token: string): void {
localStorage.setItem(this.auth.token_name, token)
}
removeToken(): void {
localStorage.removeItem(this.auth.token_name)
}
get isLoggedIn(): boolean {
return !!localStorage.getItem(this.auth.token_name)
}
genS4(): string {
return (((1 + Math.random()) * 0x10000 * Date.parse(new Date().toString())) | 0)
.toString(16)
.substring(1)
}
/**
* 日志工具(仅在 debug 模式下输出)
*
* @example
* api.logDebug('用户登录', { id: 1, name: 'test' })
* api.logDebug('请求开始', uri, params)
*/
logDebug(...args: any[]): void {
if (!this.debug) return
console.log('[DEBUG]', ...args)
}
/**
* 获取版本信息
*
* @param endpointName - 指定从哪个 endpoint 获取版本,默认使用 default endpoint
* @returns 版本信息对象
*
* @example
* // 从默认 endpoint 获取
* const versions = await api.getVersion()
*
* // 从指定 endpoint 获取
* const versions = await api.getVersion('backup')
*/
async getVersion(endpointName?: string): Promise<SimApiVersions> {
const versions: SimApiVersions = {
uiApp: typeof AppVersion === 'undefined' ? "0.0.0-develop" : AppVersion,
uiSimApi: typeof SimApiVersion === 'undefined' ? "0.0.0-develop" : SimApiVersion,
apiApp: '0.0.0',
apiSimApi: '0.0.0',
apiAppFull: '0.0.0',
apiSimApiFull: '0.0.0',
};
try {
const resp = await this.query<any>('/versions', {}, endpointName)
if (resp?.data) {
const d = resp.data
versions.apiApp = d.App?.split('+')[0] ?? '0.0.0';
versions.apiSimApi = d.SimApi?.split('+')[0] ?? '0.0.0';
versions.apiAppFull = d.App ?? '0.0.0';
versions.apiSimApiFull = d.SimApi ?? '0.0.0';
if (this.debug) {
console.log(`UI主应用版本: ${versions.uiApp}\nUISimApi版本: ${versions.uiSimApi}\nAPI主应用版本: ${versions.apiApp}\nAPISimApi版本: ${versions.apiSimApi}`)
}
return versions
}
} catch {
// 版本获取失败返回默认值
}
return versions;
}
async query<T = any>(
uri: string,
params: any = {},
endpointKey?: string,
extraHeaders?: Record<string, string>
): Promise<SimApiBaseResponse<T>> {
const headers: Record<string, string> = {...extraHeaders, ...{}}
const queryId = this.genS4()
if (!(params instanceof FormData)) {
headers['Content-Type'] = 'application/json'
}
const token = this.getToken()
if (token) {
headers['Token'] = token
}
if (this.debug) {
headers['Query-Id'] = queryId
console.log('[REQUEST*]', queryId, '->', uri, 'AUTH:', localStorage.getItem(this.auth.token_name))
}
const url = this.getEndpoint(endpointKey) + uri
try {
const respData = await fetchPost<T>(
url,
params,
headers,
this.api.timeout ?? 10000
)
if (this.debug) {
console.log('[RESPONSE]', queryId, '->', respData)
}
const processedData = this.api.responseCallback.success(respData) as SimApiBaseResponse<T>
// 业务回调处理
if (this.api.businessCallback.hasOwnProperty(processedData.code)) {
this.api.businessCallback[processedData.code](processedData)
} else if (this.api.businessCallback['common'] && processedData.code !== 200) {
this.api.businessCallback['common'](processedData)
}
// code != 200 时抛出业务错误
if (processedData.code !== 200) {
throw processedData
}
return processedData
} catch (error: any) {
if (this.debug) {
console.log('[RESPONSE]', queryId, '->', error)
}
// 网络/HTTP 错误:包装成标准响应格式抛出
if (!error?.code) {
this.api.responseCallback.error(error)
throw {
code: -1,
message: error?.message || '网络错误',
data: error,
} as SimApiBaseResponse<T>
}
// 业务错误直接抛出
throw error
}
}
async login(request: Record<string, any>): Promise<SimApiBaseResponse<string>> {
const result = await this.query<string>(this.auth.login_url, request)
if (result?.data) {
this.setToken(result.data)
}
return result
}
async logout(url?: string | null): Promise<any> {
if (url !== null) {
return this.query(url ?? this.auth.logout_url).catch(() => true)
}
this.removeToken()
return true
}
async checkLogin(url?: string | null): Promise<void> {
if (url !== null) {
await this.query(url ?? this.auth.check_url).catch(() => {
})
} else if (this.getToken()) {
this.api.businessCallback[401]?.(null)
}
}
}
}
+2
View File
@@ -14,6 +14,8 @@
"noUnusedLocals": false,
"noUnusedParameters": false,
"noFallthroughCasesInSwitch": true,
"allowJs": true,
"checkJs": false,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
+4 -6
View File
@@ -1,8 +1,7 @@
import { defineConfig, loadEnv } from 'vite'
import { defineConfig } from 'vite'
import { readFileSync } from 'node:fs'
const pkg = JSON.parse(readFileSync('./package.json', 'utf-8'))
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
build: {
outDir: 'dist',
@@ -31,8 +30,7 @@ export default defineConfig(({ mode }) => {
}
},
define: {
// SimApiVersion 由环境变量注入
'SimApiVersion': JSON.stringify(env.VITE_SimApiVersion || process.env.npm_config_SimApiVersion || '0.0.0-develop'),
SimApiVersion: JSON.stringify(pkg.version)
}
}
})