You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js项目集成next-intl与next-auth时的Edge Runtime编译错误

问题:Next.js 14 + next-auth + next-intl 构建时随机触发Edge Runtime动态代码评估错误

环境信息

  • Next.js 版本:14.2.3
  • next-auth 版本:最新版
  • next-intl 版本:3.17.2(最新版)

问题描述

构建项目时会随机出现以下编译错误,错误指向的next-auth函数不固定,可能是signIn、useSession或signOut:

Failed to compile.

./node_modules\@babel\runtime\regenerator\index.js
Dynamic Code Evaluation (e. g. 'eval', 'new Function', 'WebAssembly.compile') not allowed in Edge Runtime
Learn More: https://nextjs.org/docs/messages/edge-dynamic-code-evaluation

Import trace for requested module:
  ./node_modules\@babel\runtime\regenerator\index.js
  ./node_modules\next-auth\react\index.js
  ./src\components\interface\header\index.tsx
  ./src\components\interface\index.ts
  ./src\components\index.ts
  ./src\const\builder-by-type.ts
  ./src\const\index.ts
  ./src\middleware.ts


> Build failed because of webpack errors

本次错误追踪到header.tsx组件,该组件已声明为'use client',但仍触发错误。另外项目依赖next-intl的路由功能实现多语言(需支持5+语言),无法替换或禁用该方案。

相关代码

Header组件(src/components/interface/header/index.tsx)

'use client';

import { signIn, useSession } from 'next-auth/react';
import { useTranslations } from 'next-intl';
import { useCallback, useMemo, useState } from 'react';

import { Dropdown, IconedButton, RelativeBox, SignOutModal } from '@/components';
import { GlobeIcon, SignInIcon, SignOutIcon, WFLogo } from '@/icons';
import { flags } from '@/icons/flags';
import { AvatarVector } from '@/icons/vectors';

import s from './header.module.scss';

export const Header = () => {
   const t = useTranslations();
   const { data: session } = useSession();

   const [langDropdownOpened, setLangDropdownOpened] = useState<boolean>(false);
   const [accountDropdownOpened, setAccountDropdownOpened] = useState<boolean>(false);
   const [signOutOpened, setSignOutOpened] = useState<boolean>(false);

   const handleSignIn = () => {
      signIn('keycloak');
   };

   const dropdownOptions = useMemo<TDropdownOption[]>(
      () => [
         {
            icon: flags.Ukraine,
            label: t('Languages.ua'),
            variant: 'original',
            onClick: () => {}, // TODO add language change
         },
         {
            icon: flags.Germany,
            label: t('Languages.de'),
            variant: 'original',
            onClick: () => {}, // TODO add language change
         },
         {
            icon: flags.USA,
            label: t('Languages.en'),
            variant: 'original',
            onClick: () => {}, // TODO add language change
         },
      ],
      [],
   );

   const toggleLangDropdown = useCallback(() => setLangDropdownOpened(prev => !prev), []);
   const toggleAccountDropdown = useCallback(
      () => setAccountDropdownOpened(prev => !prev),
      [],
   );
   const toggleSignOut = useCallback(() => setSignOutOpened(prev => !prev), []);

   const signInOption: TDropdownOption = useMemo<TDropdownOption>(
      () => ({
         icon: SignInIcon,
         label: t('Components.Interface.Header.signIn'),
         onClick: handleSignIn,
         variant: 'wf-primary',
      }),
      [],
   );

   const signOutOption: TDropdownOption = useMemo<TDropdownOption>(
      () => ({
         icon: SignOutIcon,
         label: t('Components.Interface.Header.signOut'),
         onClick: toggleSignOut,
         variant: 'destructive',
      }),
      [],
   );

   const targetDropdownOption = useMemo<TDropdownOption>(
      () => (session ? signOutOption : signInOption),
      [session],
   );

   return (
      <>
         <header className={s.header}>
            <WFLogo className={s.logo} />

            <section className={s.settings}>
               <RelativeBox>
                  <IconedButton
                     onClick={toggleLangDropdown}
                     size="xl"
                     variant="transparent"
                     icon={GlobeIcon}
                     tooltipPosition="bottom"
                     tooltipText={t('Tooltips.changeLang')}
                  />

                  {langDropdownOpened && (
                     <Dropdown options={dropdownOptions} onClose={toggleLangDropdown} />
                  )}
               </RelativeBox>

               <RelativeBox>
                  <IconedButton
                     icon={AvatarVector}
                     variant="transparent"
                     size="xl"
                     onClick={toggleAccountDropdown}
                  />

                  {accountDropdownOpened && (
                     <Dropdown
                        options={[targetDropdownOption]}
                        onClose={toggleAccountDropdown}
                     />
                  )}
               </RelativeBox>
            </section>
         </header>

         {signOutOpened && (
            <SignOutModal isOpened={signOutOpened} onClose={toggleSignOut} />
         )}
      </>
   );
};

Middleware文件(src/middleware.ts)

import createMiddleware from 'next-intl/middleware';
import { locales } from '@/const';

export default createMiddleware({
   locales,
   defaultLocale: 'en',
   localeDetection: false,
});

export const config = {
   matcher: ['/((?!api|_next|.*\\..*).*)'],
};

内容的提问来源于stack exchange,提问作者Lvasche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 01:44:59