mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-14 03:30:19 +00:00
88e7d2ada1
* fix layout goback 尝试开启生产环境react debug 模式 try to fix scroll issue try to log settings layout pathname try skip path Revert "尝试移除 modal" This reverts commit 7ffac36dcb680d5a9fdda6c675ad0adb66ed13d2. remove debug try to fix again use InnerLink fix add InnerLink.tsx add debug * clean code * fix modal cancel issue
348 lines
9.5 KiB
TypeScript
348 lines
9.5 KiB
TypeScript
import analyzer from '@next/bundle-analyzer';
|
|
import { withSentryConfig } from '@sentry/nextjs';
|
|
import withSerwistInit from '@serwist/next';
|
|
import type { NextConfig } from 'next';
|
|
import ReactComponentName from 'react-scan/react-component-name/webpack';
|
|
|
|
const isProd = process.env.NODE_ENV === 'production';
|
|
const buildWithDocker = process.env.DOCKER === 'true';
|
|
const isDesktop = process.env.NEXT_PUBLIC_IS_DESKTOP_APP === '1';
|
|
const enableReactScan = !!process.env.REACT_SCAN_MONITOR_API_KEY;
|
|
const isUsePglite = process.env.NEXT_PUBLIC_CLIENT_DB === 'pglite';
|
|
|
|
// if you need to proxy the api endpoint to remote server
|
|
|
|
const basePath = process.env.NEXT_PUBLIC_BASE_PATH;
|
|
const isStandaloneMode = buildWithDocker || isDesktop;
|
|
|
|
const standaloneConfig: NextConfig = {
|
|
output: 'standalone',
|
|
outputFileTracingIncludes: { '*': ['public/**/*', '.next/static/**/*'] },
|
|
};
|
|
|
|
const nextConfig: NextConfig = {
|
|
...(isStandaloneMode ? standaloneConfig : {}),
|
|
basePath,
|
|
compress: isProd,
|
|
experimental: {
|
|
optimizePackageImports: [
|
|
'emoji-mart',
|
|
'@emoji-mart/react',
|
|
'@emoji-mart/data',
|
|
'@icons-pack/react-simple-icons',
|
|
'@lobehub/ui',
|
|
'gpt-tokenizer',
|
|
],
|
|
// oidc provider depend on constructor.name
|
|
// but swc minification will remove the name
|
|
// so we need to disable it
|
|
// refs: https://github.com/lobehub/lobe-chat/pull/7430
|
|
serverMinification: false,
|
|
webVitalsAttribution: ['CLS', 'LCP'],
|
|
},
|
|
async headers() {
|
|
return [
|
|
{
|
|
headers: [
|
|
{
|
|
key: 'x-robots-tag',
|
|
value: 'all',
|
|
},
|
|
],
|
|
source: '/:path*',
|
|
},
|
|
{
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
source: '/icons/(.*).(png|jpe?g|gif|svg|ico|webp)',
|
|
},
|
|
{
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'Vercel-CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
source: '/images/(.*).(png|jpe?g|gif|svg|ico|webp)',
|
|
},
|
|
{
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'Vercel-CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
source: '/videos/(.*).(mp4|webm|ogg|avi|mov|wmv|flv|mkv)',
|
|
},
|
|
{
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'Vercel-CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
source: '/screenshots/(.*).(png|jpe?g|gif|svg|ico|webp)',
|
|
},
|
|
{
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'Vercel-CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
source: '/og/(.*).(png|jpe?g|gif|svg|ico|webp)',
|
|
},
|
|
{
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
source: '/favicon.ico',
|
|
},
|
|
{
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
source: '/favicon-32x32.ico',
|
|
},
|
|
{
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
{
|
|
key: 'CDN-Cache-Control',
|
|
value: 'public, max-age=31536000, immutable',
|
|
},
|
|
],
|
|
source: '/apple-touch-icon.png',
|
|
},
|
|
];
|
|
},
|
|
logging: {
|
|
fetches: {
|
|
fullUrl: true,
|
|
hmrRefreshes: true,
|
|
},
|
|
},
|
|
reactStrictMode: true,
|
|
redirects: async () => [
|
|
{
|
|
destination: '/sitemap-index.xml',
|
|
permanent: true,
|
|
source: '/sitemap.xml',
|
|
},
|
|
{
|
|
destination: '/sitemap-index.xml',
|
|
permanent: true,
|
|
source: '/sitemap-0.xml',
|
|
},
|
|
{
|
|
destination: '/sitemap/plugins-1.xml',
|
|
permanent: true,
|
|
source: '/sitemap/plugins.xml',
|
|
},
|
|
{
|
|
destination: '/sitemap/assistants-1.xml',
|
|
permanent: true,
|
|
source: '/sitemap/assistants.xml',
|
|
},
|
|
{
|
|
destination: '/manifest.webmanifest',
|
|
permanent: true,
|
|
source: '/manifest.json',
|
|
},
|
|
{
|
|
destination: '/discover/assistant',
|
|
permanent: true,
|
|
source: '/discover/assistants',
|
|
},
|
|
{
|
|
destination: '/discover/plugin',
|
|
permanent: true,
|
|
source: '/discover/plugins',
|
|
},
|
|
{
|
|
destination: '/discover/model',
|
|
permanent: true,
|
|
source: '/discover/models',
|
|
},
|
|
{
|
|
destination: '/discover/provider',
|
|
permanent: true,
|
|
source: '/discover/providers',
|
|
},
|
|
{
|
|
destination: '/settings/common',
|
|
permanent: true,
|
|
source: '/settings',
|
|
},
|
|
{
|
|
destination: '/chat',
|
|
permanent: true,
|
|
source: '/welcome',
|
|
},
|
|
// TODO: 等 V2 做强制跳转吧
|
|
// {
|
|
// destination: '/settings/provider/volcengine',
|
|
// permanent: true,
|
|
// source: '/settings/provider/doubao',
|
|
// },
|
|
// we need back /repos url in the further
|
|
{
|
|
destination: '/files',
|
|
permanent: false,
|
|
source: '/repos',
|
|
},
|
|
],
|
|
// when external packages in dev mode with turbopack, this config will lead to bundle error
|
|
serverExternalPackages: isProd ? ['@electric-sql/pglite'] : undefined,
|
|
|
|
transpilePackages: ['pdfjs-dist', 'mermaid'],
|
|
|
|
webpack(config) {
|
|
config.experiments = {
|
|
asyncWebAssembly: true,
|
|
layers: true,
|
|
};
|
|
|
|
// 开启该插件会导致 pglite 的 fs bundler 被改表
|
|
if (enableReactScan && !isUsePglite) {
|
|
config.plugins.push(ReactComponentName({}));
|
|
}
|
|
|
|
// to fix shikiji compile error
|
|
// refs: https://github.com/antfu/shikiji/issues/23
|
|
config.module.rules.push({
|
|
resolve: {
|
|
fullySpecified: false,
|
|
},
|
|
test: /\.m?js$/,
|
|
type: 'javascript/auto',
|
|
});
|
|
|
|
// https://github.com/pinojs/pino/issues/688#issuecomment-637763276
|
|
config.externals.push('pino-pretty');
|
|
|
|
config.resolve.alias.canvas = false;
|
|
|
|
// to ignore epub2 compile error
|
|
// refs: https://github.com/lobehub/lobe-chat/discussions/6769
|
|
config.resolve.fallback = {
|
|
...config.resolve.fallback,
|
|
zipfile: false,
|
|
};
|
|
|
|
return config;
|
|
},
|
|
};
|
|
|
|
const noWrapper = (config: NextConfig) => config;
|
|
|
|
const withBundleAnalyzer = process.env.ANALYZE === 'true' ? analyzer() : noWrapper;
|
|
|
|
const withPWA =
|
|
isProd && !isDesktop
|
|
? withSerwistInit({
|
|
register: false,
|
|
swDest: 'public/sw.js',
|
|
swSrc: 'src/app/sw.ts',
|
|
})
|
|
: noWrapper;
|
|
|
|
const hasSentry = !!process.env.NEXT_PUBLIC_SENTRY_DSN;
|
|
const withSentry =
|
|
isProd && hasSentry
|
|
? (c: NextConfig) =>
|
|
withSentryConfig(
|
|
c,
|
|
{
|
|
org: process.env.SENTRY_ORG,
|
|
|
|
project: process.env.SENTRY_PROJECT,
|
|
// For all available options, see:
|
|
// https://github.com/getsentry/sentry-webpack-plugin#options
|
|
// Suppresses source map uploading logs during build
|
|
silent: true,
|
|
},
|
|
{
|
|
// Enables automatic instrumentation of Vercel Cron Monitors.
|
|
// See the following for more information:
|
|
// https://docs.sentry.io/product/crons/
|
|
// https://vercel.com/docs/cron-jobs
|
|
automaticVercelMonitors: true,
|
|
|
|
// Automatically tree-shake Sentry logger statements to reduce bundle size
|
|
disableLogger: true,
|
|
|
|
// Hides source maps from generated client bundles
|
|
hideSourceMaps: true,
|
|
|
|
// Transpiles SDK to be compatible with IE11 (increases bundle size)
|
|
transpileClientSDK: true,
|
|
|
|
// Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. (increases server load)
|
|
// Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
|
|
// side errors will fail.
|
|
tunnelRoute: '/monitoring',
|
|
|
|
// For all available options, see:
|
|
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
|
|
// Upload a larger set of source maps for prettier stack traces (increases build time)
|
|
widenClientFileUpload: true,
|
|
},
|
|
)
|
|
: noWrapper;
|
|
|
|
export default withBundleAnalyzer(withPWA(withSentry(nextConfig) as NextConfig));
|