feat: 升级next版本
This commit is contained in:
parent
337f0a6d33
commit
24df3f413f
|
|
@ -5,12 +5,9 @@ const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts');
|
|||
|
||||
const nextConfig: NextConfig = {
|
||||
reactStrictMode: false,
|
||||
eslint: {
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
images: {
|
||||
// 这些域不走next的image代理
|
||||
domains: ['example.com'],
|
||||
remotePatterns: [{ hostname: 'example.com', protocol: 'https' }],
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
|
|
|
|||
18
package.json
18
package.json
|
|
@ -3,8 +3,8 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev --turbopack",
|
||||
"build": "next build --turbopack",
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint",
|
||||
"format": "prettier --write .",
|
||||
|
|
@ -19,12 +19,12 @@
|
|||
"clsx": "^2.1.1",
|
||||
"js-cookie": "^3.0.5",
|
||||
"lodash": "^4.17.21",
|
||||
"next": "15.5.4",
|
||||
"next-intl": "^4.3.11",
|
||||
"next": "16.0.1",
|
||||
"next-intl": "^4.4.0",
|
||||
"qs": "^6.14.0",
|
||||
"radix-ui": "^1.4.3",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react-virtuoso": "^4.14.1",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"zustand": "^5.0.8"
|
||||
|
|
@ -36,10 +36,10 @@
|
|||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/lodash": "^4.17.20",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@types/react": "^19.2.2",
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "15.5.4",
|
||||
"eslint-config-next": "16.0.1",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-tailwindcss": "^0.6.14",
|
||||
"tailwindcss": "^4",
|
||||
|
|
|
|||
1801
pnpm-lock.yaml
1801
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -4,6 +4,7 @@ import { RightArrowIcon } from '@/assets/chatacter';
|
|||
import IconFont from '@/components/ui/iconFont';
|
||||
import ChatButton from './ChatButton';
|
||||
import Tags from '@/components/ui/Tags';
|
||||
import FormatText from '@/components/ui/format';
|
||||
|
||||
type CharacterBasicInfoProps = {
|
||||
characterId: string;
|
||||
|
|
@ -103,24 +104,22 @@ export default function CharacterBasicInfo({
|
|||
></div>
|
||||
|
||||
{/* description - 使用 section 和语义化标签 */}
|
||||
{characterDetail.description && (
|
||||
<section className="mt-10.5">
|
||||
<h2 className="flex items-center">
|
||||
<Image
|
||||
src={'/character/desc.svg'}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
className="mr-1"
|
||||
width={18}
|
||||
height={20}
|
||||
/>
|
||||
{'Description'}:
|
||||
</h2>
|
||||
<p className="text-text-color/60 mt-5 text-sm">
|
||||
{characterDetail.description}
|
||||
</p>
|
||||
</section>
|
||||
)}
|
||||
<section className="mt-10.5">
|
||||
<h2 className="flex items-center">
|
||||
<Image
|
||||
src={'/character/desc.svg'}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
className="mr-1"
|
||||
width={18}
|
||||
height={20}
|
||||
/>
|
||||
<FormatText text="common.desc" />
|
||||
</h2>
|
||||
<p className="text-text-color/60 mt-5 text-sm">
|
||||
{characterDetail.description}
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* from and chat */}
|
||||
<div className="flex items-center justify-between gap-10 pt-5">
|
||||
|
|
@ -130,7 +129,7 @@ export default function CharacterBasicInfo({
|
|||
<div className="flex items-center">
|
||||
<Image
|
||||
src={fromImage}
|
||||
alt={`${from} - 来源作品封面`}
|
||||
alt={`$来源作品封面`}
|
||||
className="rounded-lg"
|
||||
width={45}
|
||||
height={60}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1,12 +1,22 @@
|
|||
import { cookies } from 'next/headers';
|
||||
import { getRequestConfig } from 'next-intl/server';
|
||||
|
||||
// 内存缓存:存储已经加载过的语言包
|
||||
const locales: Record<string, any> = {};
|
||||
|
||||
export default getRequestConfig(async () => {
|
||||
const store = await cookies();
|
||||
const cookieLocale = store.get('locale')?.value || 'en';
|
||||
|
||||
// 如果缓存中没有这个语言,才去加载
|
||||
if (!locales[cookieLocale]) {
|
||||
locales[cookieLocale] = (
|
||||
await import(`@/locales/${cookieLocale}.ts`)
|
||||
).default;
|
||||
}
|
||||
|
||||
return {
|
||||
locale: cookieLocale,
|
||||
messages: (await import(`@/locales/${cookieLocale}.ts`)).default,
|
||||
messages: locales[cookieLocale], // 直接从缓存中读取
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ function getLocaleFromCookie(): Locale {
|
|||
if (cookieLocale && (cookieLocale === 'zh' || cookieLocale === 'en')) {
|
||||
return cookieLocale;
|
||||
}
|
||||
setLocaleToCookie('en');
|
||||
return 'en';
|
||||
}
|
||||
|
||||
|
|
@ -58,8 +59,8 @@ export function IntlProvider({ children }: IntlProviderProps) {
|
|||
useEffect(() => {
|
||||
const cookieLocale = getLocaleFromCookie();
|
||||
if (cookieLocale) {
|
||||
setLocaleState(cookieLocale);
|
||||
loadLocale(cookieLocale);
|
||||
setLocaleState(cookieLocale);
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
|
@ -76,7 +77,7 @@ export function IntlProvider({ children }: IntlProviderProps) {
|
|||
<NextIntlClientProvider
|
||||
locale={locale as any}
|
||||
messages={messages}
|
||||
timeZone="Asia/Shanghai"
|
||||
timeZone={Intl.DateTimeFormat().resolvedOptions().timeZone}
|
||||
>
|
||||
{children}
|
||||
</NextIntlClientProvider>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
export function middleware(request: NextRequest) {
|
||||
export function proxy(request: NextRequest) {
|
||||
const localeCookie = request.cookies.get('locale');
|
||||
|
||||
if (localeCookie?.value) {
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
|
|
@ -11,7 +15,7 @@
|
|||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"jsx": "react-jsx",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
|
|
@ -20,9 +24,19 @@
|
|||
],
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
".next/dev/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue