feat: 升级next版本

This commit is contained in:
liuyonghe0111 2025-11-06 17:47:54 +08:00
parent 337f0a6d33
commit 24df3f413f
9 changed files with 1129 additions and 786 deletions

View File

@ -5,12 +5,9 @@ const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts');
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
reactStrictMode: false, reactStrictMode: false,
eslint: {
ignoreDuringBuilds: true,
},
images: { images: {
// 这些域不走next的image代理 // 这些域不走next的image代理
domains: ['example.com'], remotePatterns: [{ hostname: 'example.com', protocol: 'https' }],
}, },
async rewrites() { async rewrites() {
return [ return [

View File

@ -3,8 +3,8 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev --turbopack", "dev": "next dev",
"build": "next build --turbopack", "build": "next build",
"start": "next start", "start": "next start",
"lint": "eslint", "lint": "eslint",
"format": "prettier --write .", "format": "prettier --write .",
@ -19,12 +19,12 @@
"clsx": "^2.1.1", "clsx": "^2.1.1",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"next": "15.5.4", "next": "16.0.1",
"next-intl": "^4.3.11", "next-intl": "^4.4.0",
"qs": "^6.14.0", "qs": "^6.14.0",
"radix-ui": "^1.4.3", "radix-ui": "^1.4.3",
"react": "19.1.0", "react": "19.2.0",
"react-dom": "19.1.0", "react-dom": "19.2.0",
"react-virtuoso": "^4.14.1", "react-virtuoso": "^4.14.1",
"tailwind-merge": "^3.3.1", "tailwind-merge": "^3.3.1",
"zustand": "^5.0.8" "zustand": "^5.0.8"
@ -36,10 +36,10 @@
"@types/js-cookie": "^3.0.6", "@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.20", "@types/lodash": "^4.17.20",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^19", "@types/react": "^19.2.2",
"@types/react-dom": "^19", "@types/react-dom": "^19.2.2",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "15.5.4", "eslint-config-next": "16.0.1",
"prettier": "^3.6.2", "prettier": "^3.6.2",
"prettier-plugin-tailwindcss": "^0.6.14", "prettier-plugin-tailwindcss": "^0.6.14",
"tailwindcss": "^4", "tailwindcss": "^4",

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@ import { RightArrowIcon } from '@/assets/chatacter';
import IconFont from '@/components/ui/iconFont'; import IconFont from '@/components/ui/iconFont';
import ChatButton from './ChatButton'; import ChatButton from './ChatButton';
import Tags from '@/components/ui/Tags'; import Tags from '@/components/ui/Tags';
import FormatText from '@/components/ui/format';
type CharacterBasicInfoProps = { type CharacterBasicInfoProps = {
characterId: string; characterId: string;
@ -103,24 +104,22 @@ export default function CharacterBasicInfo({
></div> ></div>
{/* description - 使用 section 和语义化标签 */} {/* description - 使用 section 和语义化标签 */}
{characterDetail.description && ( <section className="mt-10.5">
<section className="mt-10.5"> <h2 className="flex items-center">
<h2 className="flex items-center"> <Image
<Image src={'/character/desc.svg'}
src={'/character/desc.svg'} alt=""
alt="" aria-hidden="true"
aria-hidden="true" className="mr-1"
className="mr-1" width={18}
width={18} height={20}
height={20} />
/> <FormatText text="common.desc" />
{'Description'}: </h2>
</h2> <p className="text-text-color/60 mt-5 text-sm">
<p className="text-text-color/60 mt-5 text-sm"> {characterDetail.description}
{characterDetail.description} </p>
</p> </section>
</section>
)}
{/* from and chat */} {/* from and chat */}
<div className="flex items-center justify-between gap-10 pt-5"> <div className="flex items-center justify-between gap-10 pt-5">
@ -130,7 +129,7 @@ export default function CharacterBasicInfo({
<div className="flex items-center"> <div className="flex items-center">
<Image <Image
src={fromImage} src={fromImage}
alt={`${from} - 来源作品封面`} alt={`$来源作品封面`}
className="rounded-lg" className="rounded-lg"
width={45} width={45}
height={60} height={60}

View File

@ -0,0 +1,11 @@
import { getTranslations } from 'next-intl/server';
type FormatTextProps = {
text: string;
values?: any;
};
export default async function FormatText({ text, values }: FormatTextProps) {
const t = await getTranslations();
return t(text, values);
}

View File

@ -1,12 +1,22 @@
import { cookies } from 'next/headers'; import { cookies } from 'next/headers';
import { getRequestConfig } from 'next-intl/server'; import { getRequestConfig } from 'next-intl/server';
// 内存缓存:存储已经加载过的语言包
const locales: Record<string, any> = {};
export default getRequestConfig(async () => { export default getRequestConfig(async () => {
const store = await cookies(); const store = await cookies();
const cookieLocale = store.get('locale')?.value || 'en'; const cookieLocale = store.get('locale')?.value || 'en';
// 如果缓存中没有这个语言,才去加载
if (!locales[cookieLocale]) {
locales[cookieLocale] = (
await import(`@/locales/${cookieLocale}.ts`)
).default;
}
return { return {
locale: cookieLocale, locale: cookieLocale,
messages: (await import(`@/locales/${cookieLocale}.ts`)).default, messages: locales[cookieLocale], // 直接从缓存中读取
}; };
}); });

View File

@ -42,6 +42,7 @@ function getLocaleFromCookie(): Locale {
if (cookieLocale && (cookieLocale === 'zh' || cookieLocale === 'en')) { if (cookieLocale && (cookieLocale === 'zh' || cookieLocale === 'en')) {
return cookieLocale; return cookieLocale;
} }
setLocaleToCookie('en');
return 'en'; return 'en';
} }
@ -58,8 +59,8 @@ export function IntlProvider({ children }: IntlProviderProps) {
useEffect(() => { useEffect(() => {
const cookieLocale = getLocaleFromCookie(); const cookieLocale = getLocaleFromCookie();
if (cookieLocale) { if (cookieLocale) {
setLocaleState(cookieLocale);
loadLocale(cookieLocale); loadLocale(cookieLocale);
setLocaleState(cookieLocale);
} }
}, []); }, []);
@ -76,7 +77,7 @@ export function IntlProvider({ children }: IntlProviderProps) {
<NextIntlClientProvider <NextIntlClientProvider
locale={locale as any} locale={locale as any}
messages={messages} messages={messages}
timeZone="Asia/Shanghai" timeZone={Intl.DateTimeFormat().resolvedOptions().timeZone}
> >
{children} {children}
</NextIntlClientProvider> </NextIntlClientProvider>

View File

@ -1,6 +1,6 @@
import { NextRequest, NextResponse } from 'next/server'; import { NextRequest, NextResponse } from 'next/server';
export function middleware(request: NextRequest) { export function proxy(request: NextRequest) {
const localeCookie = request.cookies.get('locale'); const localeCookie = request.cookies.get('locale');
if (localeCookie?.value) { if (localeCookie?.value) {

View File

@ -1,7 +1,11 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "ES2017", "target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"], "lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true, "allowJs": true,
"skipLibCheck": true, "skipLibCheck": true,
"strict": true, "strict": true,
@ -11,7 +15,7 @@
"moduleResolution": "bundler", "moduleResolution": "bundler",
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"jsx": "preserve", "jsx": "react-jsx",
"incremental": true, "incremental": true,
"plugins": [ "plugins": [
{ {
@ -20,9 +24,19 @@
], ],
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": [
"./src/*"
]
} }
}, },
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "include": [
"exclude": ["node_modules"] "next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
} }