# mixone

[English](./README.md) | [中文](./README.zh-CN.md)

通用 Electron 桌面应用脚手架。只需依赖 `mixone`，即可开箱支持 **Vue 3 / React 19 / react-native-web** 三种渲染层，内置 Vite + Electron 快速启动方案。

## 特性
- **零配置** – `mixone create` 一键生成项目，依赖自动安装
- **三渲染层** – Vue 3、React 19、react-native-web 可选
- **TypeScript** – `--ts` 生成 TS 模板，主进程 + 渲染层全类型覆盖
- **V8 字节码** – `mixone build --bytecode` 自动编译主进程为 .jsc，保护源码
- **内置 IPC** – 窗口管理、对话框、文件系统、剪贴板、Shell API 开箱即用
- **启动闪屏** – 纯 HTML 闪屏秒出，支持自定义 splash.html
- **依赖收敛** – vue/react/vite/electron/bytenode 等全由 mixone 提供

## 快速开始
```bash
# 创建项目
npm create mixone@latest my-app

# 或全局安装后创建
npm install -g mixone
mixone create my-app
```

```bash
cd my-app
npm run dev      # 开发模式（Vite + Electron，支持 HMR）
npm run build    # 构建渲染层到 dist/
npm run start    # 启动（electron .）
```

## CLI 命令

### mixone create

```bash
mixone create <name> [options]
```

| 参数 | 说明 |
|------|------|
| `--template vue\|react\|react-native-web` | 选择渲染层（默认 vue） |
| `--ts` | 生成 TypeScript 模板 |
| `--ui <lib>` | 选择 UI 库（见下方） |
| `--yes` | 跳过交互确认 |
| `--skip-install` | 跳过 npm install |
| `--force` | 覆盖已有目录 |

### mixone dev

启动开发模式。自动检测 TS 项目并编译主进程，端口被占用时自动切换。
```bash
mixone dev              # 自动从 5173 开始检测
mixone dev --port 3000  # 从指定端口开始检测
```

### mixone build

构建渲染层到 `dist/`。
```bash
mixone build              # 仅构建渲染层
mixone build --bytecode   # 构建 + 编译主进程为 V8 字节码
```

### mixone build:bytecode

仅编译主进程字节码（不构建渲染层）。
```bash
mixone build:bytecode
```

### 其他命令

```bash
mixone doctor    # 检查环境与项目状态
mixone list      # 列出可用模板和 UI 库
```

## 模板

| 模板 | 说明 |
|------|------|
| `vue` | Vue 3 + vue-router（默认） |
| `react` | React 19 + react-router |
| `react-native-web` | React Native Web + react-router |

配合 `--ts` 生成 TypeScript 变体。
```bash
mixone create app --template vue --ts
mixone create app --template react --ts
```

## UI 库
| 渲染层 | 可选 UI 库 |
|--------|-----------|
| vue | `element-plus`、`ant-design-vue`、`naive-ui`、`vuetify` |
| react | `antd`、`mui`、`mantine` |

```bash
mixone create app --template vue --ui element-plus
mixone create app --template react --ui antd
```

不选 UI 库直接回车即可。
## 项目结构

```
my-app/
├── main.js                 # Electron 主进程（CommonJS）
├── preload.js              # contextBridge IPC 桥接
├── appConfig.js            # userData/缓存重定向到系统临时目录
├── mixone.vite.config.js   # Vite 配置
├── package.json            # 依赖 mixone + electron-builder
├── tsconfig.json           # TypeScript 配置（--ts 模式）
└── src/                    # 渲染层
    ├── main.js             # 入口
    ├── App.vue / App.jsx   # 根组件
    ├── router.js           # 路由配置
    ├── components/         # 可复用组件
    ├── utils/              # 工具函数
    ├── assets/             # 静态资源
    └── views/ / pages/     # 页面组件
```

## 内置 IPC
生成的项目通过 `window.mixone` 暴露以下 API：
```js
const mixone = window.mixone

// 系统信息
mixone.platform    // 'win32' | 'darwin' | 'linux'
mixone.version     // Electron 版本
mixone.node        // Node.js 版本

// 窗口管理
mixone.window.open({ url: 'https://example.com', width: 800, height: 600 })
mixone.window.openModal({ url: '/sub', width: 520, height: 420 })
mixone.window.close()
mixone.window.minimize()
mixone.window.maximize()

// 对话框
await mixone.dialog.openFile({ filters: [{ name: 'Text', extensions: ['txt'] }] })
await mixone.dialog.saveFile({ defaultPath: 'untitled.txt' })
await mixone.dialog.messageBox({ type: 'info', message: 'Hello' })

// 文件系统
const { content } = await mixone.fs.readText('/path/to/file')
await mixone.fs.writeText('/path/to/file', 'content')
const { entries } = await mixone.fs.readDir('/path/to/dir')
await mixone.fs.mkdir('/path/to/dir', { recursive: true })
await mixone.fs.rename('/old', '/new')
await mixone.fs.copyFile('/src', '/dest')
await mixone.fs.appendText('/path', 'more')
const { data } = await mixone.fs.readJson('/config.json')
await mixone.fs.writeJson('/config.json', { key: 'value' })

// 剪贴板
await mixone.clipboard.writeText('hello')
const text = await mixone.clipboard.readText()
await mixone.clipboard.writeHtml('<b>bold</b>')
await mixone.clipboard.clear()

// Shell
await mixone.shell.openExternal('https://example.com')
await mixone.shell.showItemInFolder('/path/to/file')
mixone.shell.beep()

// 应用
const info = await mixone.app.info()
mixone.app.relaunch()
mixone.app.quit()
```

## 打包发布

模板已内置 electron-builder 配置，直接运行：

```bash
npm run build:desktop    # 构建 + 打包当前平台
```

输出目录：`release/`

## V8 字节码
`mixone build --bytecode` 会将 main.js、preload.js、appConfig.js 编译成 .jsc 字节码文件，保护源码。
```bash
mixone build --bytecode           # 构建 + 字节码
MIXONE_NO_BYTECODE=1 mixone build  # 禁用字节码
```

或在 package.json 中设置：

```json
{ "mixone": { "bytecode": false } }
```

## 自定义闪屏
在项目根目录创建 `splash.html` 即可替换默认闪屏。
```html
<!DOCTYPE html>
<html>
<head><style>body { background: #0f172a; color: white; }</style></head>
<body><h1>Loading...</h1></body>
</html>
```

## 机制

- **launcher 模式** – Vite dev server 在 Node 进程内直接 spawn（不经过 Electron），就绪后再 spawn Electron 连接 dev server，启动速度更快
- **依赖收敛** – vue/react/vite/electron/typescript/bytenode 等全由 mixone 提供
- **缓存隔离** – userData/sessionData/chromium-cache 重定向到 `%TEMP%/<包名>`，避免多实例冲突

## 贡献

- Issue 反馈：https://github.com/qew4/mixone-example/issues
- 附上 `mixone doctor` 输出与最小复现步骤
## License

MIT
