My Next.js project started failing to compile in build time once i introduced Next-auth dependency to handle social-login within providers (google) and credential login using email/password.
here's the log of the error during the build of the project
Failed to compile.
./node_modules/@babel/runtime/helpers/construct.js
Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Middleware pages/_middleware
Import trace for requested module:
./node_modules/@babel/runtime/helpers/wrapNativeSuper.js
./node_modules/next-auth/core/errors.js
./node_modules/next-auth/lib/logger.js
./node_modules/next-auth/react/index.js
./lib/apolloClient.ts
./lib/apollo.tsx
./src/service/serverFetcherQuery.ts
./src/pages/_middleware.ts
./node_modules/@babel/runtime/helpers/isNativeFunction.js
Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Middleware pages/_middleware
Import trace for requested module:
./node_modules/@babel/runtime/helpers/wrapNativeSuper.js
./node_modules/next-auth/core/errors.js
./node_modules/next-auth/lib/logger.js
./node_modules/next-auth/react/index.js
./lib/apolloClient.ts
./lib/apollo.tsx
./src/service/serverFetcherQuery.ts
./src/pages/_middleware.ts
> Build failed because of webpack errors
Searching similar issues online i found out that you cannot invoke GetSession()
from next-auth in _middleware, that is not my case because i use my middleware to check the presence of a cookie:
/**
* If the user doesn't have a theme-color cookie, set one
* @param {NextRequest} req - NextRequest - The request object from Next.js
* @returns A function that takes a NextRequest and returns a NextResponse
*/
export async function middleware(req: NextRequest) {
const response = NextResponse.next()
if (!req.cookies[COOKIE_NAME]) {
const themeColors = await GetThemeServerSide()
const nextUrl = req.nextUrl.clone()
const responseWithCookie = NextResponse.rewrite(nextUrl)
responseWithCookie.cookie(COOKIE_NAME, JSON.stringify(themeColors), {
httpOnly: true
})
return responseWithCookie
}
return response
}
where GetThemeServerSide is a simple function that fetches a graphql query:
export const GetThemeServerSide = async () => {
const { data }: { data?: GetThemeQuery } = await apolloClient.query({
query: GET_THEME
})
return data?.theme?.data?.attributes
}
I use GetSession only in my apolloClient Link to insert The bearer token in Headers for next request
import { getSession } from 'next-auth/react'
const authLink = setContext(async (_, { headers }) => {
if (typeof window !== 'undefined') {
if (!token) {
const session = await getSession()
token = session?.accessToken as string
}
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : ''
}
}
}
return {
headers: {}
}
})
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: from([authLink, errorLink, httpLink]),
...other apollo related config
})
version of npm packages:
"dependencies": {
"@apollo/client": "^3.5.10",
"gql": "^1.1.2",
"graphql": "^16.3.0",
"next": "12.1.0",
"next-auth": "^4.3.4",
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
i figured it out, as juliomalves suggested that the apollo client auth link was the problem because the nextjs middleware is incapable of tree-shaking at the moment.
I dedicated a new apollo client instance context free for all server-side graphql calls