feat: 首页 Go SSR 与 React hydrate 同构,消壳层与帖行闪动

补齐侧栏/右栏图标与徽章、鉴权种子、StaticFeedList,并修正嵌套 a 与标题徽章对齐。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-01 07:07:38 +08:00
parent 9e134916a4
commit 44eed97fe0
26 changed files with 2530 additions and 159 deletions

View File

@@ -1,13 +1,40 @@
import path from 'path';
import { defineConfig } from 'vite';
import { defineConfig, type Plugin } from 'vite';
import react from '@vitejs/plugin-react';
// 与 Go 后端默认端口一致,可通过 VITE_API_PORT 覆盖
const apiPort = process.env.VITE_API_PORT || '3000';
const apiTarget = `http://localhost:${apiPort}`;
/** 把 stylesheet 挪到 head 靠前(先于 module script接近 Gitea 外链 CSS 顺序 */
function htmlStylesheetsFirst(): Plugin {
return {
name: 'html-stylesheets-first',
enforce: 'post',
transformIndexHtml(html) {
// 只处理真实标签,忽略注释里的示例文字
const linkRe = /<link\b(?![^>]*\/?>)[^>]*\brel=["']stylesheet["'][^>]*>\s*/gi;
// 更稳妥:逐个找 link 标签
const styles: string[] = [];
const out = html.replace(/<link\b[^>]*>/gi, (tag) => {
if (/\brel=["']stylesheet["']/i.test(tag)) {
styles.push(tag);
return '';
}
return tag;
});
if (!styles.length) return html;
const inject = `${styles.join('\n ')}\n `;
if (/<script\b/i.test(out)) {
return out.replace(/<script\b/i, `${inject}<script`);
}
return out.replace(/<\/head>/i, ` ${inject}</head>`);
},
};
}
export default defineConfig({
plugins: [react()],
plugins: [react(), htmlStylesheetsFirst()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),