19 KiB
项目优化实施计划
面向 AI 代理的工作者: 必需子技能:使用 superpowers:subagent-driven-development(推荐)或 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框(
- [ ])语法来跟踪进度。
目标: 根据代码审查报告,修复所有必须修复的问题,完成建议的优化项,提升项目整体质量。
架构: 纯静态 Next.js 网站,修复 TypeScript 配置问题,清理无效配置,优化测试环境,改进代码组织结构。
技术栈: Next.js 16, React 19, TypeScript, Jest, Playwright
文件结构
将要修改的文件
| 文件 | 职责 | 变更类型 |
|---|---|---|
tsconfig.json |
TypeScript 配置 | 修改 - 添加 Jest 类型支持 |
next.config.ts |
Next.js 配置 | 修改 - 移除无效 headers 配置 |
src/contexts/theme-context.tsx |
主题上下文 | 修改 - 简化为纯静态版本 |
src/app/layout.tsx |
根布局 | 修改 - 移除暗色主题脚本 |
package.json |
项目配置 | 修改 - 清理无效脚本 |
e2e/website-acceptance.spec.ts |
E2E 测试 | 修改 - 支持环境变量 URL |
e2e/playwright.config.ts |
Playwright 配置 | 修改 - 添加 baseURL 配置 |
nginx-static.conf |
Nginx 配置 | 修改 - 添加安全头 |
将要创建的文件
| 文件 | 职责 |
|---|---|
src/lib/constants/index.ts |
常量导出入口 |
src/lib/constants/company.ts |
公司信息常量 |
src/lib/constants/navigation.ts |
导航配置 |
src/lib/constants/services.ts |
服务数据 |
src/lib/constants/products.ts |
产品数据 |
src/lib/constants/news.ts |
新闻数据 |
src/lib/constants/stats.ts |
统计数据 |
将要删除的文件
| 文件 | 原因 |
|---|---|
| 无 | 本次优化不删除文件 |
阶段一:P0 必须修复(立即处理)
任务 1:修复 TypeScript 测试类型错误
文件:
- 修改:
tsconfig.json
问题: 测试文件中 describe、it、expect、beforeEach 等全局类型未定义,导致 npm run type-check 失败。
- 步骤 1:修改 tsconfig.json 添加 Jest 类型支持
{
"compilerOptions": {
"target": "ES2017",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"types": ["jest", "node"],
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": [
"./src/*"
]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts",
"**/*.mts",
"dist/types/**/*.ts",
"dist/dev/types/**/*.ts"
],
"exclude": [
"node_modules",
"e2e"
]
}
- 步骤 2:运行类型检查验证修复
运行:npm run type-check
预期:无测试相关的类型错误
- 步骤 3:Commit
git add tsconfig.json
git commit -m "fix: 添加 Jest 类型支持,修复测试文件类型错误"
阶段二:P1 建议修改(短期优化)
任务 2:移除无效的 headers 配置
文件:
- 修改:
next.config.ts - 修改:
nginx-static.conf
问题: output: 'export' 静态导出模式下,headers 配置不会生效。应将安全头配置移至 nginx。
- 步骤 1:简化 next.config.ts,移除 headers 配置
import type { NextConfig } from "next";
const cdnDomain = process.env.CDN_DOMAIN || '';
const nextConfig: NextConfig = {
distDir: 'dist',
output: 'export',
assetPrefix: cdnDomain || undefined,
images: {
unoptimized: true,
},
compress: true,
poweredByHeader: false,
reactStrictMode: true,
experimental: {
optimizePackageImports: ['lucide-react'],
},
compiler: {
removeConsole: process.env.NODE_ENV === 'production',
},
};
export default nextConfig;
- 步骤 2:更新 nginx-static.conf 添加安全头
读取当前 nginx-static.conf 内容后追加安全头配置。
- 步骤 3:运行构建验证配置正确
运行:npm run build
预期:构建成功,无错误
- 步骤 4:Commit
git add next.config.ts nginx-static.conf
git commit -m "refactor: 移除无效的 headers 配置,安全头移至 nginx"
任务 3:简化 ThemeContext 为纯静态版本
文件:
- 修改:
src/contexts/theme-context.tsx - 修改:
src/app/layout.tsx
问题: ThemeProvider 硬编码只返回 'light',但 layout.tsx 中还有暗色主题切换脚本,两者不一致。纯静态网站不需要主题切换。
- 步骤 1:简化 theme-context.tsx
'use client';
import { createContext, useContext, type ReactNode } from 'react';
interface ThemeContextType {
theme: 'light';
resolvedTheme: 'light';
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export function ThemeProvider({ children }: { children: ReactNode }) {
return (
<ThemeContext.Provider value={{ theme: 'light', resolvedTheme: 'light' }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme() {
const context = useContext(ThemeContext);
if (context === undefined) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
}
- 步骤 2:修改 layout.tsx 移除暗色主题脚本
移除 <head> 中的暗色主题检测脚本:
// 移除以下代码块:
<script
dangerouslySetInnerHTML={{
__html: `
try {
const theme = localStorage.getItem('ruixin-theme') || 'system';
if (theme === 'dark' || (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
}
} catch {}
`,
}}
/>
- 步骤 3:运行类型检查验证修改
运行:npm run type-check
预期:无错误
- 步骤 4:Commit
git add src/contexts/theme-context.tsx src/app/layout.tsx
git commit -m "refactor: 简化主题上下文为纯静态版本,移除暗色主题切换逻辑"
任务 4:清理无效的 npm 脚本
文件:
- 修改:
package.json
问题: 部分脚本引用不存在的文件,如 audit:all、test:performance、test:stress 等。
- 步骤 1:检查哪些脚本文件存在
ls -la scripts/run-all-tests.sh 2>/dev/null || echo "不存在"
ls -la tests/performance/ 2>/dev/null || echo "不存在"
- 步骤 2:移除无效脚本,保留有效的脚本
修改 package.json 的 scripts 部分:
{
"scripts": {
"dev": "next dev -p 3000",
"build": "next build",
"start": "npx serve dist -p 3000",
"lint": "eslint",
"type-check": "tsc --noEmit",
"preview": "npx serve dist -p 3000",
"test": "cd e2e && npx playwright test --config=playwright.config.ts",
"test:unit": "jest",
"test:coverage": "jest --coverage",
"test:coverage:check": "jest --coverage --ci",
"coverage:report": "open coverage/lcov-report/index.html",
"test:e2e": "cd e2e && npm test",
"test:smoke": "cd e2e && npx playwright test --grep @smoke",
"check:contrast": "tsx scripts/utils/check-color-contrast.ts",
"check:headings": "tsx scripts/utils/check-heading-hierarchy.ts",
"lighthouse": "lhci autorun",
"lighthouse:collect": "lhci collect",
"lighthouse:assert": "lhci assert",
"lighthouse:upload": "lhci upload",
"lighthouse:desktop": "lhci autorun --settings.preset=desktop",
"lighthouse:mobile": "lhci autorun --settings.preset=mobile",
"deploy:cdn": "bash scripts/deploy-cdn.sh",
"deploy:cdn:refresh": "bash scripts/refresh-cdn.sh",
"prepare": "husky"
}
}
- 步骤 3:运行 npm run 验证脚本有效
运行:npm run
预期:列出所有可用脚本,无错误
- 步骤 4:Commit
git add package.json
git commit -m "chore: 清理无效的 npm 脚本命令"
任务 5:修复 E2E 测试硬编码 URL
文件:
- 修改:
e2e/playwright.config.ts - 修改:
e2e/website-acceptance.spec.ts
问题: E2E 测试硬编码 https://novalon.cn,无法在本地或测试环境运行。
- 步骤 1:检查 playwright.config.ts 当前配置
读取 e2e/playwright.config.ts 内容。
- 步骤 2:修改 playwright.config.ts 添加 baseURL
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: process.env.E2E_BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
webServer: {
command: 'npm run preview',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120000,
},
});
- 步骤 3:修改 website-acceptance.spec.ts 使用相对路径
将所有硬编码 URL 改为相对路径:
import { test, expect } from '@playwright/test';
test.describe('网站全面测试验收', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
});
test('首页加载正常', async ({ page }) => {
await expect(page).toHaveTitle(/四川睿新致远科技有限公司/);
await expect(page.locator('header')).toBeVisible();
await expect(page.locator('footer')).toBeVisible();
});
// ... 其他测试用例,将 https://novalon.cn 替换为空或相对路径
test('联系我们页面没有显示公司电话', async ({ page }) => {
await page.goto('/contact');
await page.waitForLoadState('networkidle');
// ...
});
test('关于我们页面没有显示公司电话', async ({ page }) => {
await page.goto('/about');
await page.waitForLoadState('networkidle');
// ...
});
test('联系我们页面表单正常显示', async ({ page }) => {
await page.goto('/contact');
await page.waitForLoadState('networkidle');
// ...
});
test('页面跳转功能正常', async ({ page }) => {
await page.click('text=联系我们');
await page.waitForLoadState('networkidle');
expect(page.url()).toContain('/contact');
await page.click('text=首页');
await page.waitForLoadState('networkidle');
expect(page.url()).toBe(process.env.E2E_BASE_URL || 'http://localhost:3000/');
});
// ...
});
- 步骤 4:运行 E2E 测试验证修改
运行:npm run test
预期:测试可以正常运行(需要先构建)
- 步骤 5:Commit
git add e2e/playwright.config.ts e2e/website-acceptance.spec.ts
git commit -m "fix: E2E 测试支持环境变量 URL,可在本地运行"
任务 6:更新 Jest 配置路径
文件:
- 修改:
config/test/jest.config.js
问题: setupFilesAfterEnv 指向 <rootDir>/jest.setup.js,但实际文件在根目录。
- 步骤 1:检查 jest.setup.js 位置
确认 jest.setup.js 在项目根目录。
- 步骤 2:修改 jest.config.js 路径
const path = require('path');
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
roots: ['<rootDir>/../src'],
testMatch: ['**/__tests__/**/*.test.{ts,tsx}', '**/*.test.{ts,tsx}'],
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!src/**/*.d.ts',
'!src/**/*.stories.{ts,tsx}',
'!src/**/__tests__/**',
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
coverageReporters: ['text', 'lcov', 'html', 'json'],
coverageDirectory: '<rootDir>/../coverage',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/../src/$1',
},
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
transformIgnorePatterns: [
'node_modules/(?!(nanoid|next-auth|@auth)/)',
],
setupFilesAfterEnv: ['<rootDir>/../jest.setup.js'],
testTimeout: 10000,
verbose: true,
maxWorkers: '50%',
};
- 步骤 3:运行单元测试验证配置
运行:npm run test:unit
预期:测试正常运行
- 步骤 4:Commit
git add config/test/jest.config.js
git commit -m "fix: 修正 Jest 配置中的文件路径"
阶段三:P2 仅供参考(长期改进)
任务 7:拆分 constants.ts 文件
文件:
- 创建:
src/lib/constants/index.ts - 创建:
src/lib/constants/company.ts - 创建:
src/lib/constants/navigation.ts - 创建:
src/lib/constants/services.ts - 创建:
src/lib/constants/products.ts - 创建:
src/lib/constants/news.ts - 创建:
src/lib/constants/stats.ts - 删除:
src/lib/constants.ts - 修改:所有导入 constants 的文件
问题: constants.ts 文件过大(20KB+),包含所有业务数据,不利于维护。
- 步骤 1:创建 company.ts
export const COMPANY_INFO = {
name: '四川睿新致远科技有限公司',
shortName: '睿新致遠',
slogan: '智连未来,成长伙伴',
description: '以智慧连接数字趋势,以伙伴身份陪您成长——您的数字化转型同行者',
founded: '2026',
location: '四川省成都市',
email: 'contact@novalon.cn',
address: '中国四川省成都市龙泉驿区幸福路12号',
icp: '蜀ICP备2026013658号',
police: '川公网安备51010602003285号',
} as const;
- 步骤 2:创建 navigation.ts
export interface NavigationItem {
id: string;
label: string;
href: string;
}
export const NAVIGATION: NavigationItem[] = [
{ id: 'home', label: '首页', href: '/' },
{ id: 'services', label: '核心业务', href: '/' },
{ id: 'products', label: '产品服务', href: '/' },
{ id: 'cases', label: '成功案例', href: '/' },
{ id: 'about', label: '关于我们', href: '/' },
{ id: 'news', label: '新闻动态', href: '/' },
{ id: 'contact', label: '联系我们', href: '/contact' },
];
- 步骤 3:创建 stats.ts
export interface StatItem {
value: string;
label: string;
}
export const STATS: StatItem[] = [
{ value: '10+', label: '企业客户' },
{ value: '20+', label: '成功案例' },
{ value: '30+', label: '项目交付' },
{ value: '12+', label: '年行业经验' },
];
- 步骤 4:创建 services.ts
从原 constants.ts 提取 SERVICES 数据。
- 步骤 5:创建 products.ts
从原 constants.ts 提取 PRODUCTS 数据。
- 步骤 6:创建 news.ts
export type NewsCategory = '公司新闻' | '产品发布' | '合作动态' | '行业资讯';
export interface NewsItem {
id: string;
title: string;
excerpt: string;
date: string;
category: NewsCategory;
image: string;
content: string;
}
export const NEWS: NewsItem[] = [
// 从原 constants.ts 提取
];
- 步骤 7:创建 index.ts 统一导出
export * from './company';
export * from './navigation';
export * from './stats';
export * from './services';
export * from './products';
export * from './news';
- 步骤 8:删除原 constants.ts
rm src/lib/constants.ts
- 步骤 9:运行类型检查验证重构
运行:npm run type-check
预期:无错误
- 步骤 10:运行测试验证功能正常
运行:npm run test:unit
预期:所有测试通过
- 步骤 11:Commit
git add src/lib/constants/
git rm src/lib/constants.ts
git commit -m "refactor: 拆分 constants.ts 为模块化结构"
任务 8:清理过时的计划文档
文件:
- 删除:
docs/plans/目录下已完成的计划文档
问题: docs/plans/ 目录下有大量计划文档,部分已过时。
- 步骤 1:列出所有计划文档
ls -la docs/plans/
- 步骤 2:评估每个文档是否需要保留
保留:
- 与当前项目架构相关的文档
删除:
-
已完成的临时计划
-
与 CMS 相关的计划
-
已过时的测试优化计划
-
步骤 3:删除过时文档
rm docs/plans/2025-03-13-intelligent-tiered-test-optimization.md
rm docs/plans/2026-03-09-production-readiness-plan.md
rm docs/plans/2026-03-09-test-coverage-improvement-plan.md
rm docs/plans/2026-03-10-full-module-test-coverage-plan.md
rm docs/plans/2026-03-10-gradual-coverage-improvement.md
rm docs/plans/2026-03-10-phased-launch-implementation-plan.md
rm docs/plans/2026-03-10-production-readiness-execution-plan.md
rm docs/plans/2026-03-10-test-coverage-improvement-plan.md
rm docs/plans/2026-03-20-quality-improvement-iteration.md
rm docs/plans/2026-03-24-code-quality-tools-integration.md
rm docs/plans/2026-03-24-contact-form-security-enhancement.md
rm docs/plans/2026-03-28-monorepo-multi-site-architecture.md
- 步骤 4:Commit
git add docs/plans/
git commit -m "docs: 清理过时的计划文档"
阶段四:验证与收尾
任务 9:全面验证
- 步骤 1:运行类型检查
npm run type-check
预期:无错误
- 步骤 2:运行 lint 检查
npm run lint
预期:无错误
- 步骤 3:运行单元测试
npm run test:unit
预期:所有测试通过
- 步骤 4:运行构建
npm run build
预期:构建成功
- 步骤 5:本地预览验证
npm run preview
手动验证:
-
首页加载正常
-
导航功能正常
-
各页面链接正常
-
样式显示正确
-
步骤 6:最终 Commit
git add -A
git commit -m "chore: 完成项目优化,通过全面验证"
执行顺序总结
| 阶段 | 任务 | 优先级 | 预计时间 |
|---|---|---|---|
| 阶段一 | 任务 1:修复 TypeScript 类型错误 | P0 | 10 分钟 |
| 阶段二 | 任务 2:移除无效 headers 配置 | P1 | 15 分钟 |
| 阶段二 | 任务 3:简化 ThemeContext | P1 | 10 分钟 |
| 阶段二 | 任务 4:清理无效脚本 | P1 | 10 分钟 |
| 阶段二 | 任务 5:修复 E2E 测试 URL | P1 | 20 分钟 |
| 阶段二 | 任务 6:更新 Jest 配置 | P1 | 10 分钟 |
| 阶段三 | 任务 7:拆分 constants.ts | P2 | 30 分钟 |
| 阶段三 | 任务 8:清理过时文档 | P2 | 10 分钟 |
| 阶段四 | 任务 9:全面验证 | 必须 | 15 分钟 |
总预计时间: 约 2 小时
风险与注意事项
- 任务 7(拆分 constants) 可能影响较多文件,建议最后执行
- 任务 5(E2E 测试) 需要先构建才能运行
- 每个任务完成后立即 commit,便于回滚
- 如遇阻塞,可跳过 P2 任务,优先完成 P0 和 P1