109 lines
3.8 KiB
TypeScript
109 lines
3.8 KiB
TypeScript
import { copyFileSync, mkdirSync } from 'node:fs'
|
||
import { resolve } from 'node:path'
|
||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
||
import react from '@vitejs/plugin-react'
|
||
import tailwindcss from '@tailwindcss/vite'
|
||
import type { Plugin } from 'vite'
|
||
|
||
/** 构建期把主题 token 样式表拷到 out/renderer/tokens.css:
|
||
* 生产环境 src/ 不进包,插件页经 peer://assets/tokens.css 引用它保证深浅色/accent 连续 */
|
||
function copyTokensCss(): Plugin {
|
||
return {
|
||
name: 'aso-copy-tokens-css',
|
||
closeBundle() {
|
||
const src = resolve(__dirname, 'src/renderer/src/styles/beautifului.css')
|
||
const outDir = resolve(__dirname, 'out/renderer')
|
||
try {
|
||
mkdirSync(outDir, { recursive: true })
|
||
copyFileSync(src, resolve(outDir, 'tokens.css'))
|
||
} catch (err) {
|
||
this.warn(`tokens.css 拷贝失败: ${err instanceof Error ? err.message : String(err)}`)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/** 构建期把插件存储 worker(免打包纯 ESM,只依赖 node 内置模块)拷到 out/main/ 旁:
|
||
* 主进程按 import.meta.url 定位它——必须与主进程产物同目录 */
|
||
function copyStorageWorker(): Plugin {
|
||
return {
|
||
name: 'aso-copy-storage-worker',
|
||
closeBundle() {
|
||
const src = resolve(__dirname, 'src/main/plugins/storage-worker.mjs')
|
||
const outDir = resolve(__dirname, 'out/main')
|
||
try {
|
||
mkdirSync(outDir, { recursive: true })
|
||
copyFileSync(src, resolve(outDir, 'storage-worker.mjs'))
|
||
} catch (err) {
|
||
this.warn(`storage-worker.mjs 拷贝失败: ${err instanceof Error ? err.message : String(err)}`)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
export default defineConfig({
|
||
main: {
|
||
// pi SDK 为纯 ESM 包,主进程输出 ESM(Electron ≥28 支持)
|
||
plugins: [externalizeDepsPlugin(), copyStorageWorker()],
|
||
build: {
|
||
rollupOptions: {
|
||
// electron 保持内置模块导入;pi 全家桶运行时从 node_modules 以 ESM 加载,
|
||
// 同时避开 pi 实验性导出引用的未声明子包问题
|
||
external: ['electron', /^@earendil-works\//],
|
||
output: {
|
||
format: 'es',
|
||
entryFileNames: '[name].mjs'
|
||
}
|
||
}
|
||
},
|
||
resolve: {
|
||
alias: {
|
||
'@main': resolve(__dirname, 'src/main'),
|
||
'@shared': resolve(__dirname, 'src/shared')
|
||
}
|
||
}
|
||
},
|
||
preload: {
|
||
plugins: [externalizeDepsPlugin()],
|
||
build: {
|
||
rollupOptions: {
|
||
// electron 解析为内置模块,避免把 npm 包打进 preload
|
||
external: ['electron'],
|
||
output: {
|
||
format: 'cjs',
|
||
// "type":"module" 下 .js 会被当 ESM 加载,preload 必须用 .cjs
|
||
entryFileNames: '[name].cjs'
|
||
}
|
||
}
|
||
},
|
||
resolve: {
|
||
alias: {
|
||
'@shared': resolve(__dirname, 'src/shared')
|
||
}
|
||
}
|
||
},
|
||
renderer: {
|
||
// Windows 上 Hyper-V/WSL 的 WinNAT 每次开机会随机保留若干端口段,
|
||
// 默认 5173 常被圈进保留段导致 EACCES;固定用 5323 避开(若日后再撞,
|
||
// 可换端口,或管理员执行 net stop winnat && net start winnat 后
|
||
// netsh int ipv4 add excludedportrange protocol=tcp startport=<端口> numberofports=1 永久占用)
|
||
server: {
|
||
port: 5323,
|
||
// 允许 dev server 读取工作区源码包(@aso/plugin-sdk 从 packages/ 链接进来)
|
||
fs: { allow: [resolve(__dirname, '../..')] }
|
||
},
|
||
optimizeDeps: {
|
||
// sdk 是源码形态(exports 指向 .ts/.tsx),必须走源码 transform 而非预打包
|
||
exclude: ['@aso/plugin-sdk']
|
||
},
|
||
plugins: [react(), tailwindcss(), copyTokensCss()],
|
||
resolve: {
|
||
alias: {
|
||
'@': resolve(__dirname, 'src/renderer/src'),
|
||
'@renderer': resolve(__dirname, 'src/renderer/src'),
|
||
'@shared': resolve(__dirname, 'src/shared')
|
||
}
|
||
}
|
||
}
|
||
})
|