feat: add Vite host and Gitea CI for project57 embed
CI Pipeline / check-commit (push) Successful in 9s
CI Pipeline / build (push) Has been skipped
CI Pipeline / deploy-only (push) Has been skipped
CI Pipeline / deploy (push) Has been skipped

This commit is contained in:
mdszxy committed 2026-10-05 15:27:42 +08:00
commit 076e603c93
12 files changed
+901

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
node_modules
.pnpm-store
.pnpm-debug.log
.git
.gitignore
.gitattributes
.gitea
.github
.env
.env.local
.env.*.local
.vscode
.idea
*.swp
.DS_Store
Thumbs.db
*.log
README.md
*.md
tmp
temp
+2
View File
@@ -0,0 +1,2 @@
# A 站(project57)源站,用于加载 aurora.js 以及图片 / API
VITE_A_ORIGIN=http://localhost:3000
+255
View File
@@ -0,0 +1,255 @@
# 对齐 project0(projectBase)CI:Gitea + Docker + K8s
# 本仓为 Vite 静态宿主,构建产物为 dist/,镜像用 nginx 监听 3000
name: CI Pipeline
on:
push:
branches: [master]
workflow_dispatch:
jobs:
check-commit:
runs-on: ubuntu-latest
outputs:
should_build: ${{ steps.check.outputs.should_build }}
should_deploy: ${{ steps.check.outputs.should_deploy }}
should_deploy_only: ${{ steps.check.outputs.should_deploy_only }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
lfs: false
fetch-depth: 1
- name: Check commit message
id: check
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "should_build=true" >> $GITHUB_OUTPUT
echo "should_deploy=true" >> $GITHUB_OUTPUT
echo "should_deploy_only=false" >> $GITHUB_OUTPUT
echo "✅ 手动触发"
else
head_msg="${{ github.event.head_commit.message }}"
echo "检查提交消息: $head_msg"
if echo "$head_msg" | grep -qE '\[deploy-only\]'; then
echo "should_build=false" >> $GITHUB_OUTPUT
echo "should_deploy=true" >> $GITHUB_OUTPUT
echo "should_deploy_only=true" >> $GITHUB_OUTPUT
echo "✅ 找到 [deploy-only] 标记,只执行部署(跳过构建)"
elif echo "$head_msg" | grep -qE '\[build\]|\[deploy\]'; then
echo "should_build=true" >> $GITHUB_OUTPUT
echo "should_deploy_only=false" >> $GITHUB_OUTPUT
echo "✅ 找到 [build] 或 [deploy] 标记"
if echo "$head_msg" | grep -qE '\[deploy\]'; then
echo "should_deploy=true" >> $GITHUB_OUTPUT
echo "✅ 找到 [deploy] 标记,将执行构建和部署"
else
echo "should_deploy=false" >> $GITHUB_OUTPUT
echo "✅ 只找到 [build] 标记,只执行构建"
fi
else
echo "should_build=false" >> $GITHUB_OUTPUT
echo "should_deploy=false" >> $GITHUB_OUTPUT
echo "should_deploy_only=false" >> $GITHUB_OUTPUT
echo "ℹ️ 提交消息不包含 [build]、[deploy] 或 [deploy-only] 标记,跳过工作流"
fi
fi
build:
needs: check-commit
if: needs.check-commit.outputs.should_build == 'true'
runs-on: ubuntu-latest
outputs:
image_ref: ${{ steps.push.outputs.image_ref }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
lfs: false
persist-credentials: true
token: ${{ secrets.LFS_PAT || secrets.GITHUB_TOKEN }}
- name: Force LFS Pull with Custom Auth
run: |
HOST="git.bigmonk.org"
REPO_PATH="${{ github.repository }}"
if [ -z "${{ secrets.LFS_PAT }}" ]; then
echo "❌ 错误: 未配置 LFS_PAT Secret"
exit 1
fi
GIT_TOKEN="${{ secrets.LFS_PAT }}"
git config --local --unset credential.helper || true
git config --global --unset credential.helper || true
AUTH_REMOTE="https://x-access-token:${GIT_TOKEN}@${HOST}/${REPO_PATH}.git"
AUTH_LFS_URL="https://x-access-token:${GIT_TOKEN}@${HOST}/${REPO_PATH}.git/info/lfs"
git remote set-url origin "${AUTH_REMOTE}"
git config --local lfs.url "${AUTH_LFS_URL}"
git lfs install
git lfs pull
echo "✅ LFS files pulled successfully"
- name: Setup Node.js and pnpm
uses: actions/setup-node@v4
with:
node-version: '24'
- name: Install pnpm
run: |
corepack enable
corepack prepare [email protected] --activate
- name: Configure npm cache proxy and retries
run: |
echo "NPM_CONFIG_REGISTRY=http://172.17.0.1:4873" >> $GITHUB_ENV
echo "npm_config_registry=http://172.17.0.1:4873" >> $GITHUB_ENV
echo "PNPM_CONFIG_REGISTRY=http://172.17.0.1:4873" >> $GITHUB_ENV
pnpm config set registry http://172.17.0.1:4873
pnpm config set fetch-retries 6
pnpm config set fetch-retry-factor 2
pnpm config set fetch-retry-mintimeout 20000
pnpm config set fetch-retry-maxtimeout 120000
pnpm config set network-concurrency 8
pnpm config set child-concurrency 4
- name: Install dependencies
run: |
pnpm install --frozen-lockfile --prefer-offline \
|| pnpm install --frozen-lockfile --prefer-offline --registry=https://registry.npmjs.org
- name: Build Vite application
env:
VITE_A_ORIGIN: ${{ secrets.VITE_A_ORIGIN }}
run: |
if [ -z "${VITE_A_ORIGIN}" ]; then
echo "❌ 未配置 Secret VITE_A_ORIGIN(A 站源站,如 https://swissicapital.net)"
exit 1
fi
echo "VITE_A_ORIGIN=${VITE_A_ORIGIN}"
pnpm build
echo "✅ Build completed"
if [ -d "dist" ] && [ -f "dist/index.html" ]; then
echo "✅ dist/index.html 存在"
else
echo "❌ dist 构建产物不存在"
exit 1
fi
- name: Verify Docker access
run: docker info
- name: Build Docker image
run: |
export REGISTRY="104.225.236.253:30500"
export REPO_NAME="${{ github.event.repository.name }}"
export IMAGE_LATEST="${REGISTRY}/${REPO_NAME}:latest"
export IMAGE_SHA="${REGISTRY}/${REPO_NAME}:${GITHUB_SHA}"
docker build -t "${IMAGE_LATEST}" -t "${IMAGE_SHA}" .
echo "Image built: ${IMAGE_LATEST}"
echo "Image built: ${IMAGE_SHA}"
- name: Push to registry (SHA + latest, deploy by digest)
id: push
run: |
set -euo pipefail
export REGISTRY="104.225.236.253:30500"
export REPO_NAME="${{ github.event.repository.name }}"
export IMAGE_LATEST="${REGISTRY}/${REPO_NAME}:latest"
export IMAGE_SHA="${REGISTRY}/${REPO_NAME}:${GITHUB_SHA}"
docker push "${IMAGE_SHA}"
docker push "${IMAGE_LATEST}"
IMAGE_REF="${IMAGE_SHA}"
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "${IMAGE_SHA}" 2>/dev/null || true)
if [ -n "${DIGEST}" ]; then
IMAGE_REF="${DIGEST}"
fi
echo "image_ref=${IMAGE_REF}" >> "${GITHUB_OUTPUT}"
echo "✅ Pushed ${IMAGE_SHA} and ${IMAGE_LATEST}"
echo "✅ Rollout ref (digest preferred): ${IMAGE_REF}"
deploy:
needs: [check-commit, build]
if: needs.check-commit.outputs.should_deploy == 'true' && needs.check-commit.outputs.should_deploy_only != 'true'
runs-on: ubuntu-latest
steps:
- name: Deploy to K8s
run: |
if [ -z "${{ secrets.KUBECONFIG_BASE64 }}" ]; then
echo "INFO: KUBECONFIG_BASE64 not configured. Deployment skipped."
exit 0
fi
mkdir -p ~/.kube
echo "${{ secrets.KUBECONFIG_BASE64 }}" | base64 -d > ~/.kube/config
chmod 600 ~/.kube/config
kubectl cluster-info || { echo "ERROR: Failed to connect to K8s cluster"; exit 1; }
export REPO_NAME="${{ github.event.repository.name }}"
export IMAGE_REF="${{ needs.build.outputs.image_ref }}"
export NAMESPACE="ns-${REPO_NAME}"
export DEPLOYMENT="${REPO_NAME}-deploy"
echo "Deploying ${IMAGE_REF} to ${NAMESPACE}/${DEPLOYMENT}"
kubectl patch "deployment/${DEPLOYMENT}" -n "${NAMESPACE}" --type='json' -p='[
{"op":"replace","path":"/spec/strategy/rollingUpdate/maxSurge","value":"100%"},
{"op":"replace","path":"/spec/strategy/rollingUpdate/maxUnavailable","value":0},
{"op":"replace","path":"/spec/template/spec/containers/0/image","value":"'"${IMAGE_REF}"'"},
{"op":"replace","path":"/spec/template/spec/containers/0/imagePullPolicy","value":"IfNotPresent"},
{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/httpGet/path","value":"/api/health"},
{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/timeoutSeconds","value":5},
{"op":"replace","path":"/spec/template/spec/containers/0/livenessProbe/httpGet/path","value":"/api/health"},
{"op":"replace","path":"/spec/template/spec/containers/0/livenessProbe/timeoutSeconds","value":5}
]'
kubectl rollout status "deployment/${DEPLOYMENT}" -n "${NAMESPACE}" --timeout=180s
echo "✅ Deployment completed successfully"
deploy-only:
needs: check-commit
if: needs.check-commit.outputs.should_deploy_only == 'true'
runs-on: ubuntu-latest
steps:
- name: Deploy to K8s (without build)
run: |
if [ -z "${{ secrets.KUBECONFIG_BASE64 }}" ]; then
echo "INFO: KUBECONFIG_BASE64 not configured. Deployment skipped."
exit 0
fi
mkdir -p ~/.kube
echo "${{ secrets.KUBECONFIG_BASE64 }}" | base64 -d > ~/.kube/config
chmod 600 ~/.kube/config
kubectl cluster-info || { echo "ERROR: Failed to connect to K8s cluster"; exit 1; }
export REGISTRY="104.225.236.253:30500"
export REPO_NAME="${{ github.event.repository.name }}"
export IMAGE_LATEST="${REGISTRY}/${REPO_NAME}:latest"
export NAMESPACE="ns-${REPO_NAME}"
export DEPLOYMENT="${REPO_NAME}-deploy"
echo "Deploying existing image ${IMAGE_LATEST} to ${NAMESPACE}/${DEPLOYMENT}"
kubectl patch "deployment/${DEPLOYMENT}" -n "${NAMESPACE}" --type='json' -p='[
{"op":"replace","path":"/spec/strategy/rollingUpdate/maxSurge","value":"100%"},
{"op":"replace","path":"/spec/strategy/rollingUpdate/maxUnavailable","value":0},
{"op":"replace","path":"/spec/template/spec/containers/0/image","value":"'"${IMAGE_LATEST}"'"},
{"op":"replace","path":"/spec/template/spec/containers/0/imagePullPolicy","value":"Always"},
{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/httpGet/path","value":"/api/health"},
{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/timeoutSeconds","value":5},
{"op":"replace","path":"/spec/template/spec/containers/0/livenessProbe/httpGet/path","value":"/api/health"},
{"op":"replace","path":"/spec/template/spec/containers/0/livenessProbe/timeoutSeconds","value":5}
]'
kubectl rollout status "deployment/${DEPLOYMENT}" -n "${NAMESPACE}" --timeout=180s
echo "✅ Deployment completed (using existing image)"
+4
View File
@@ -0,0 +1,4 @@
node_modules
dist
.env
.DS_Store
+5
View File
@@ -0,0 +1,5 @@
# CI 中先 pnpm build 产出 dist/,镜像只负责托管静态文件
FROM nginx:1.27-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY dist /usr/share/nginx/html
EXPOSE 3000
+33
View File
@@ -0,0 +1,33 @@
# project57-x
B 站宿主:跨域加载 A 站(project57)打包的前台 SPA。
CI 对齐 **project0**(本地 `projectBase`):提交信息带 `[deploy]` 会构建镜像并部署到 K8s。
本仓是 Vite 静态站,构建产物为 `dist/`,Docker 用 nginx 监听 **3000**,并提供 `/api/health` 给探针。
仓库 Secrets 需配置(与 project0 相同,外加 A 站地址):
- `LFS_PAT`
- `KUBECONFIG_BASE64`
- `VITE_A_ORIGIN`:A 站线上源站,如 `https://swissicapital.net`
## 本地运行
1. A 站先打包嵌入脚本并启动:
```bash
cd ../project57
pnpm build:embed
pnpm dev
```
2. 本仓库安装并启动(默认 http://localhost:4173):
```bash
pnpm install
pnpm dev
```
3. 若 A 站端口不是 `3000`,复制 `.env.example` 为 `.env`,改 `VITE_A_ORIGIN`。
页面会加载 `${VITE_A_ORIGIN}/embed/aurora.js`,图片和联系表单也走 A 站。路由为 hash,例如 `http://localhost:4173/#/kontakt`。
+33
View File
@@ -0,0 +1,33 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>project57-x</title>
<style>
html,
body {
margin: 0;
min-height: 100%;
}
#aurora-root {
min-height: 100vh;
}
#aurora-error {
display: none;
margin: 24px;
padding: 16px 18px;
max-width: 640px;
border: 1px solid #f0c2c2;
background: #fff5f5;
color: #8a1f1f;
font: 14px/1.5 system-ui, sans-serif;
}
</style>
</head>
<body>
<div id="aurora-error"></div>
<div id="aurora-root"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
+16
View File
@@ -0,0 +1,16 @@
server {
listen 3000;
server_name _;
root /usr/share/nginx/html;
index index.html;
location = /api/health {
default_type text/plain;
add_header Content-Type text/plain;
return 200 "ok";
}
location / {
try_files $uri $uri/ /index.html;
}
}
+14
View File
@@ -0,0 +1,14 @@
{
"name": "project57-x",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview --port 3000 --strictPort --host"
},
"devDependencies": {
"vite": "^8.3.2"
}
}
+440
View File
@@ -0,0 +1,440 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
devDependencies:
vite:
specifier: ^8.3.2
version: 8.3.2
packages:
'@oxc-project/[email protected]':
resolution: {integrity: sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==}
'@rolldown/[email protected]':
resolution: {integrity: sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@rolldown/[email protected]':
resolution: {integrity: sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@rolldown/[email protected]':
resolution: {integrity: sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@rolldown/[email protected]':
resolution: {integrity: sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@rolldown/[email protected]':
resolution: {integrity: sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@rolldown/[email protected]':
resolution: {integrity: sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@rolldown/[email protected]':
resolution: {integrity: sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rolldown/[email protected]':
resolution: {integrity: sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rolldown/[email protected]':
resolution: {integrity: sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rolldown/[email protected]':
resolution: {integrity: sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rolldown/[email protected]':
resolution: {integrity: sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rolldown/[email protected]':
resolution: {integrity: sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@rolldown/[email protected]':
resolution: {integrity: sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@rolldown/[email protected]':
resolution: {integrity: sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@rolldown/[email protected]':
resolution: {integrity: sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
'@rolldown/[email protected]':
resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
[email protected]:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
[email protected]:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
peerDependencies:
picomatch: ^3 || ^4
peerDependenciesMeta:
picomatch:
optional: true
[email protected]:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
[email protected]:
resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [android]
[email protected]:
resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [darwin]
[email protected]:
resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [darwin]
[email protected]:
resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [freebsd]
[email protected]:
resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm]
os: [linux]
[email protected]:
resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
[email protected]:
resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
[email protected]:
resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
[email protected]:
resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
[email protected]:
resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [win32]
[email protected]:
resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [win32]
[email protected]:
resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
engines: {node: '>= 12.0.0'}
[email protected]:
resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
[email protected]:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
[email protected]:
resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==}
engines: {node: '>=12'}
[email protected]:
resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==}
engines: {node: ^10 || ^12 || >=14}
[email protected]:
resolution: {integrity: sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
[email protected]:
resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==}
engines: {node: '>=0.10.0'}
[email protected]:
resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
engines: {node: '>=12.0.0'}
[email protected]:
resolution: {integrity: sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
'@types/node': ^20.19.0 || >=22.12.0
'@vitejs/devtools': ^0.7.1
esbuild: ^0.27.0 || ^0.28.0
jiti: '>=1.21.0'
less: ^4.0.0
sass: ^1.70.0
sass-embedded: ^1.70.0
stylus: '>=0.54.8'
sugarss: ^5.0.0
terser: ^5.16.0
tsx: ^4.8.1
yaml: ^2.4.2
peerDependenciesMeta:
'@types/node':
optional: true
'@vitejs/devtools':
optional: true
esbuild:
optional: true
jiti:
optional: true
less:
optional: true
sass:
optional: true
sass-embedded:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
tsx:
optional: true
yaml:
optional: true
snapshots:
'@oxc-project/[email protected]': {}
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]':
optional: true
'@rolldown/[email protected]': {}
[email protected]: {}
[email protected]([email protected]):
optionalDependencies:
picomatch: 4.0.7
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
optional: true
[email protected]:
dependencies:
detect-libc: 2.1.2
optionalDependencies:
lightningcss-android-arm64: 1.33.0
lightningcss-darwin-arm64: 1.33.0
lightningcss-darwin-x64: 1.33.0
lightningcss-freebsd-x64: 1.33.0
lightningcss-linux-arm-gnueabihf: 1.33.0
lightningcss-linux-arm64-gnu: 1.33.0
lightningcss-linux-arm64-musl: 1.33.0
lightningcss-linux-x64-gnu: 1.33.0
lightningcss-linux-x64-musl: 1.33.0
lightningcss-win32-arm64-msvc: 1.33.0
lightningcss-win32-x64-msvc: 1.33.0
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]:
dependencies:
nanoid: 3.3.19
picocolors: 1.1.1
source-map-js: 1.2.2
[email protected]:
dependencies:
'@oxc-project/types': 0.152.0
'@rolldown/pluginutils': 1.0.1
optionalDependencies:
'@rolldown/binding-android-arm-eabi': 1.2.12
'@rolldown/binding-android-arm64': 1.2.12
'@rolldown/binding-darwin-arm64': 1.2.12
'@rolldown/binding-darwin-x64': 1.2.12
'@rolldown/binding-freebsd-x64': 1.2.12
'@rolldown/binding-linux-arm-gnueabihf': 1.2.12
'@rolldown/binding-linux-arm64-gnu': 1.2.12
'@rolldown/binding-linux-arm64-musl': 1.2.12
'@rolldown/binding-linux-ppc64-gnu': 1.2.12
'@rolldown/binding-linux-s390x-gnu': 1.2.12
'@rolldown/binding-linux-x64-gnu': 1.2.12
'@rolldown/binding-linux-x64-musl': 1.2.12
'@rolldown/binding-openharmony-arm64': 1.2.12
'@rolldown/binding-win32-arm64-msvc': 1.2.12
'@rolldown/binding-win32-x64-msvc': 1.2.12
[email protected]: {}
[email protected]:
dependencies:
fdir: 6.5.0([email protected])
picomatch: 4.0.7
[email protected]:
dependencies:
lightningcss: 1.33.0
picomatch: 4.0.7
postcss: 8.5.28
rolldown: 1.2.12
tinyglobby: 0.2.17
optionalDependencies:
fsevents: 2.3.3
+66
View File
@@ -0,0 +1,66 @@
const A_ORIGIN = (import.meta.env.VITE_A_ORIGIN || "http://localhost:3000").replace(
/\/$/,
""
);
const errorEl = document.getElementById("aurora-error");
function showError(message: string) {
if (!errorEl) return;
errorEl.style.display = "block";
errorEl.textContent = message;
}
function loadScript(src: string): Promise<void> {
return new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = src;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject(new Error(`无法加载 ${src}`));
document.head.appendChild(script);
});
}
async function boot() {
try {
await loadScript(`${A_ORIGIN}/embed/aurora.js`);
} catch {
showError(
`无法加载 A 站脚本:${A_ORIGIN}/embed/aurora.js。请先在 project57 执行 pnpm build:embed 并启动 A 站,或修改 .env 中的 VITE_A_ORIGIN。`
);
return;
}
const api = window.AuroraSite;
if (!api?.mount) {
showError("A 站脚本已加载,但未找到 AuroraSite.mount。");
return;
}
api.mount("#aurora-root", {
assetBase: A_ORIGIN,
apiBase: A_ORIGIN,
cssUrl: `${A_ORIGIN}/embed/aurora.css`,
history: "hash",
});
}
boot();
declare global {
interface Window {
AuroraSite?: {
mount: (
target: string | Element,
options?: {
assetBase?: string;
apiBase?: string;
cssUrl?: string;
history?: "hash" | "browser";
basename?: string;
}
) => { unmount: () => void };
};
}
}
+12
View File
@@ -0,0 +1,12 @@
import { defineConfig } from "vite";
export default defineConfig({
server: {
port: 4173,
strictPort: true,
},
preview: {
port: 4173,
strictPort: true,
},
});