优化 GitHub Pages 部署配置,支持 master 分支,更新 Node.js 版本,调整构建命令,添加详细部署说明
This commit is contained in:
parent
5064d43bdb
commit
b6accfc111
9
.github/workflows/deploy.yml
vendored
9
.github/workflows/deploy.yml
vendored
@ -3,7 +3,7 @@ name: Deploy to GitHub Pages
|
||||
on:
|
||||
# 当推送到main分支时触发
|
||||
push:
|
||||
branches: [ main ]
|
||||
branches: [ main, master ]
|
||||
|
||||
# 允许手动触发工作流
|
||||
workflow_dispatch:
|
||||
@ -30,14 +30,13 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Build for GitHub Pages
|
||||
run: npm run build:github
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v4
|
||||
|
78
DEPLOYMENT.md
Normal file
78
DEPLOYMENT.md
Normal file
@ -0,0 +1,78 @@
|
||||
# 部署说明
|
||||
|
||||
本项目支持多种部署方式,每种方式都有对应的构建命令。
|
||||
|
||||
## 🚀 部署方式
|
||||
|
||||
### 1. GitHub Pages(自动部署)
|
||||
|
||||
**特点**:推送代码到 `main` 或 `master` 分支后自动部署
|
||||
**URL格式**:`https://username.github.io/obs-overlay-widget/`
|
||||
|
||||
**设置步骤**:
|
||||
1. 推送代码到GitHub仓库
|
||||
2. 在仓库设置中启用GitHub Pages
|
||||
- 进入 Settings → Pages
|
||||
- Source 选择 "GitHub Actions"
|
||||
3. GitHub Actions会自动构建和部署
|
||||
|
||||
### 2. 手动部署(任意服务器)
|
||||
|
||||
**特点**:适用于任何Web服务器,包括Apache、Nginx、静态托管服务等
|
||||
**构建命令**:
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
**部署步骤**:
|
||||
1. 运行构建命令
|
||||
2. 将 `dist` 文件夹中的所有文件上传到服务器
|
||||
3. 可以部署到根目录或任何子目录
|
||||
|
||||
### 3. GitHub Pages(手动构建)
|
||||
|
||||
**特点**:如果你需要手动为GitHub Pages构建
|
||||
**构建命令**:
|
||||
```bash
|
||||
npm run build:github
|
||||
```
|
||||
|
||||
## 📝 构建命令说明
|
||||
|
||||
| 命令 | 用途 | base路径 | 适用场景 |
|
||||
|------|------|----------|----------|
|
||||
| `npm run dev` | 开发服务器 | `/` | 本地开发 |
|
||||
| `npm run build` | 生产构建 | `./` | 手动部署到任意服务器 |
|
||||
| `npm run build:github` | GitHub Pages构建 | `/obs-overlay-widget/` | 手动GitHub Pages部署 |
|
||||
| `npm run preview` | 预览构建结果 | - | 本地测试构建结果 |
|
||||
|
||||
## 🛠️ 技术说明
|
||||
|
||||
### Base路径配置
|
||||
|
||||
项目使用智能的base路径配置:
|
||||
|
||||
- **开发模式**:使用 `/` 作为base路径
|
||||
- **生产模式**:
|
||||
- 默认使用 `./`(相对路径),适用于任何部署位置
|
||||
- 如果设置了 `VITE_BASE_PATH` 环境变量,则使用指定路径
|
||||
|
||||
### 自动化部署
|
||||
|
||||
GitHub Actions工作流(`.github/workflows/deploy.yml`)会:
|
||||
1. 检测代码变更
|
||||
2. 安装依赖
|
||||
3. 使用 `npm run build:github` 构建项目
|
||||
4. 自动部署到GitHub Pages
|
||||
|
||||
## 🔧 自定义部署
|
||||
|
||||
如果你的仓库名不是 `obs-overlay-widget`,需要修改:
|
||||
|
||||
1. **vite.config.ts** 中的仓库名
|
||||
2. **package.json** 中 `build:github` 脚本的路径
|
||||
|
||||
例如,如果仓库名是 `my-widget`:
|
||||
```json
|
||||
"build:github": "vue-tsc -b && cross-env VITE_BASE_PATH=/my-widget/ vite build"
|
||||
```
|
109
package-lock.json
generated
109
package-lock.json
generated
@ -15,8 +15,10 @@
|
||||
"vue-router": "^4.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.4",
|
||||
"@vitejs/plugin-vue": "^6.0.0",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"typescript": "~5.8.3",
|
||||
"vite": "^7.0.0",
|
||||
"vue-tsc": "^2.2.10"
|
||||
@ -862,6 +864,16 @@
|
||||
"@types/lodash": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-24.0.4.tgz",
|
||||
"integrity": "sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/web-bluetooth": {
|
||||
"version": "0.0.16",
|
||||
"resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
||||
@ -1193,6 +1205,40 @@
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-env": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz",
|
||||
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"cross-env": "src/bin/cross-env.js",
|
||||
"cross-env-shell": "src/bin/cross-env-shell.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.14",
|
||||
"npm": ">=6",
|
||||
"yarn": ">=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
|
||||
@ -1343,6 +1389,13 @@
|
||||
"he": "bin/he"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
|
||||
@ -1435,6 +1488,16 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
|
||||
@ -1522,6 +1585,29 @@
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
@ -1562,6 +1648,13 @@
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.8.0.tgz",
|
||||
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-7.0.0.tgz",
|
||||
@ -1696,6 +1789,22 @@
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"node-which": "bin/node-which"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc -b && vite build",
|
||||
"build:github": "vue-tsc -b && cross-env VITE_BASE_PATH=/obs-overlay-widget/ vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -16,8 +17,10 @@
|
||||
"vue-router": "^4.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.0.4",
|
||||
"@vitejs/plugin-vue": "^6.0.0",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"typescript": "~5.8.3",
|
||||
"vite": "^7.0.0",
|
||||
"vue-tsc": "^2.2.10"
|
||||
|
@ -182,7 +182,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import type { TimerConfig } from './types';
|
||||
import type { TimerConfig, TimerMode } from './types';
|
||||
|
||||
// Define props with default values
|
||||
const props = withDefaults(defineProps<{
|
||||
@ -271,12 +271,13 @@ onMounted(() => {
|
||||
// Preset styles
|
||||
const presets = {
|
||||
gaming: {
|
||||
mode: 'countdown',
|
||||
mode: 'countdown' as TimerMode,
|
||||
duration: 1800, // 30分钟
|
||||
format: 'mm:ss',
|
||||
fontSize: 64,
|
||||
fontFamily: 'Impact',
|
||||
fontWeight: 'bold',
|
||||
color: '#ff6b35',
|
||||
useGradient: true,
|
||||
gradientColors: ['#ff6b35', '#f7931e'],
|
||||
textShadow: true,
|
||||
@ -288,10 +289,13 @@ const presets = {
|
||||
warningThreshold: 60,
|
||||
warningColor: '#ff0000',
|
||||
playSound: true,
|
||||
soundVolume: 80
|
||||
soundVolume: 80,
|
||||
autoStart: false,
|
||||
showMilliseconds: false,
|
||||
finishedColor: '#ff0000'
|
||||
},
|
||||
meeting: {
|
||||
mode: 'countdown',
|
||||
mode: 'countdown' as TimerMode,
|
||||
duration: 3600, // 60分钟
|
||||
format: 'hh:mm:ss',
|
||||
fontSize: 52,
|
||||
@ -299,6 +303,7 @@ const presets = {
|
||||
fontWeight: 'normal',
|
||||
color: '#2ecc71',
|
||||
useGradient: false,
|
||||
gradientColors: ['#2ecc71', '#27ae60'],
|
||||
textShadow: true,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.3)',
|
||||
shadowBlur: 4,
|
||||
@ -309,24 +314,36 @@ const presets = {
|
||||
warningColor: '#f39c12',
|
||||
finishedColor: '#e74c3c',
|
||||
playSound: true,
|
||||
soundVolume: 60
|
||||
soundVolume: 60,
|
||||
autoStart: false,
|
||||
showMilliseconds: false
|
||||
},
|
||||
workout: {
|
||||
mode: 'stopwatch',
|
||||
mode: 'stopwatch' as TimerMode,
|
||||
duration: 0,
|
||||
format: 'mm:ss',
|
||||
fontSize: 72,
|
||||
fontFamily: 'JetBrains Mono',
|
||||
fontWeight: 'bold',
|
||||
color: '#e74c3c',
|
||||
useGradient: true,
|
||||
gradientColors: ['#e74c3c', '#c0392b'],
|
||||
textShadow: true,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)',
|
||||
shadowBlur: 6,
|
||||
showMilliseconds: true,
|
||||
autoStart: false
|
||||
autoStart: false,
|
||||
showProgress: false,
|
||||
progressColor: '#e74c3c',
|
||||
progressHeight: 4,
|
||||
warningThreshold: 0,
|
||||
warningColor: '#f39c12',
|
||||
finishedColor: '#e74c3c',
|
||||
playSound: false,
|
||||
soundVolume: 50
|
||||
},
|
||||
minimal: {
|
||||
mode: 'countdown',
|
||||
mode: 'countdown' as TimerMode,
|
||||
duration: 300,
|
||||
format: 'mm:ss',
|
||||
fontSize: 48,
|
||||
@ -334,10 +351,20 @@ const presets = {
|
||||
fontWeight: 'lighter',
|
||||
color: '#ffffff',
|
||||
useGradient: false,
|
||||
gradientColors: ['#ffffff', '#f8f9fa'],
|
||||
textShadow: false,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)',
|
||||
shadowBlur: 4,
|
||||
showProgress: false,
|
||||
progressColor: '#ffffff',
|
||||
progressHeight: 4,
|
||||
warningThreshold: 30,
|
||||
warningColor: '#f39c12',
|
||||
finishedColor: '#e74c3c',
|
||||
playSound: false,
|
||||
autoStart: false
|
||||
soundVolume: 50,
|
||||
autoStart: false,
|
||||
showMilliseconds: false
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
|
||||
import type { TimerConfig, TimerStatus, TimerMode } from './types';
|
||||
import type { TimerConfig, TimerStatus } from './types';
|
||||
|
||||
// Define props with default values
|
||||
const props = withDefaults(defineProps<{
|
||||
@ -125,8 +125,8 @@ const progressFillStyle = computed(() => {
|
||||
|
||||
// 容器样式
|
||||
const containerStyle = computed(() => ({
|
||||
textAlign: 'center',
|
||||
userSelect: 'none'
|
||||
textAlign: 'center' as const,
|
||||
userSelect: 'none' as const
|
||||
}));
|
||||
|
||||
// 计时器显示样式
|
||||
@ -292,7 +292,7 @@ watch(() => props.config.duration, (newDuration) => {
|
||||
}
|
||||
});
|
||||
|
||||
watch(() => props.config.mode, (newMode) => {
|
||||
watch(() => props.config.mode, () => {
|
||||
resetTimer();
|
||||
});
|
||||
|
||||
|
@ -1,8 +1,29 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
base: process.env.NODE_ENV === 'production' ? '/obs-overlay-widget/' : '/',
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
// 加载环境变量
|
||||
const env = loadEnv(mode, process.cwd(), '')
|
||||
|
||||
// 根据构建环境动态设置base路径
|
||||
const base = (() => {
|
||||
// 开发模式使用根路径
|
||||
if (command === 'serve') {
|
||||
return '/'
|
||||
}
|
||||
|
||||
// 生产模式检查是否有指定的base路径(用于GitHub Pages)
|
||||
if (env.VITE_BASE_PATH) {
|
||||
return env.VITE_BASE_PATH
|
||||
}
|
||||
|
||||
// 默认使用相对路径,适用于任何部署场景
|
||||
return './'
|
||||
})()
|
||||
|
||||
return {
|
||||
plugins: [vue()],
|
||||
base,
|
||||
}
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user