User9712
User9712

Reputation: 127

Disabled SWC as replacement for Babel because of custom Babel configuration in Next.js 14

I'm working on a Next.js 14 project and when I run npm run dev, I get the following error:

npm run dev

> [email protected] dev
> next dev

 ⚠ Port 3000 is in use, trying 3001 instead.
   ▲ Next.js 14.1.0
   - Local:        http://localhost:3001

 ⚠ Invalid next.config.mjs options detected: 
 ⚠     Unrecognized key(s) in object: 'optimizeFonts' at "experimental"
 ⚠ See more info here: https://nextjs.org/docs/messages/invalid-next-config
   Disabled SWC as replacement for Babel because of custom Babel configuration ".babelrc" https://nextjs.org/docs/messages/swc-disabled
 ✓ Ready in 1350ms
   Using external babel configuration from /Users/(omission)/Documents/Personal/React/my-portfolio/.babelrc
 ⚠ It looks like there is a custom Babel configuration that can be removed.
 ○ Compiling /not-found ...
 ⨯ ./src/app/layout.tsx:2:1
Syntax error: "next/font" requires SWC although Babel is being used due to a custom babel config being present.
Read more: https://nextjs.org/docs/messages/babel-font-loader-conflict
 ⨯ ./src/app/layout.tsx:2:1
Syntax error: "next/font" requires SWC although Babel is being used due to a custom babel config being present.
Read more: https://nextjs.org/docs/messages/babel-font-loader-conflict
 ✓ Compiled / in 80ms (417 modules)
 ⚠ Fast Refresh had to perform a full reload. Read more: https://nextjs.org/docs/messages/fast-refresh-reload

This error seems to be caused by some conflict between SWC's "next/font" settings and my custom Babel configuration. My project is still using Babel because I want to use Jest to test my Next.js components.

I initially set up my project following the instructions on this website(in Japanese), which included setting up a custom Babel configuration.

instructions on the website

  1. Install the necessary modules (Assuming a Next.js project has already been created)
npm i -D jest @testing-library/react @types/jest @testing-library/jest-dom @testing-library/dom babel-jest @testing-library/user-event jest-css-modules
  1. Configure the .babelrc file
{
    "presets": ["next/babel"]
}
  1. Add Jest configuration to package.json
"jest": {
    "testPathIgnorePatterns": [
        "<rootDir>/.next/",         // Exclude from tests
        "<rootDir>/node_modules/"
    ],
    "moduleNameMapper": {          // Mock CSS files using jest-css-modules
        "\\.(css)$": "<rootDir>/node_modules/jest-css-modules"
    }
}
  1. Add a test script to package.json
"scripts": {
    ...
    "test": "jest --env=jsdom --verbose"  // Add this
},

My test script:

import "@testing-library/jest-dom/";
import { render, screen } from "@testing-library/react";
import Page from "../src/app/page";

// testing the page component

test("renders the page", () => {
  render(<Page />);
  expect(screen.getByText(/Get started by editing/)).toBeInTheDocument();
});

My project structure:

enter image description here

What I've tried:

- Disable the font optimization feature: I've disabled the font optimization feature in my next.config.mjs file with the following code, but the same error showed up when I went to my local host.
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    optimizeFonts: false,
  },
};

export default nextConfig;

Environment:

Is there a way to solve this problem?
Or is there any other way to use Jest in my project?
Any advice would be appreciated.

Upvotes: 4

Views: 1134

Answers (2)

Ethan
Ethan

Reputation: 1637

Using Babel along side SWC

If you want to use SWC despite the presence of a .babelrc file you can force it in your next.config.js file.

SWC disabled | Next.js docs

This will make sure you don't have to disable font optimization or any of SWC's other other features.

Replace Babel

I would not recommend using Babel if the only reason is to keep Jest working. You can use SWC with Jest. Simply add the follwing to your jest.config.js file:

const nextJest = require('next/jest')
 
/** @type {import('jest').Config} */
const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: './',
})
 
// Add any custom config to be passed to Jest
const config = {
  coverageProvider: 'v8',
  testEnvironment: 'jsdom',
  // Add more setup options before each test is run
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}
 
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(config)

See Testing: Jest | Next.js docs.

Use Vitest over Jest

This personally is what I would do. See the Vitest comparison to understand it's advantages. Vitest is a drop in Jest replacement too. See this article for how to do so.

Upvotes: 1

audeos
audeos

Reputation: 336

You can remove Babel from your project and use the NextJS SWC compiler to run Jest.

https://nextjs.org/docs/architecture/nextjs-compiler#jest

Basically you will have to remove any babel configuration files and uninstall babel from your project completely (you won't need it anymore).

Then create a jest.config.js file that might look something like this:

const nextJest = require('next/jest')

// Providing the path to your Next.js app which will enable loading
// next.config.js and .env files
const createJestConfig = nextJest({ dir: './' })

// Any custom config you want to pass to Jest
const customJestConfig = {
    moduleNameMapper: {
        "^@/(.*)$": "<rootDir>/src/$1"
    }
}

// createJestConfig is exported in this way to ensure that next/jest can load
// the Next.js configuration, which is async
module.exports = createJestConfig(customJestConfig)

Upvotes: 0

Related Questions