diff --git a/packages/next/shared/lib/loadable.js b/packages/next/shared/lib/loadable.js index ea2a1fe754500..629bab95c7c2f 100644 --- a/packages/next/shared/lib/loadable.js +++ b/packages/next/shared/lib/loadable.js @@ -96,7 +96,11 @@ function createLoadableComponent(loadFn, options) { // Client only if (!initialized && typeof window !== 'undefined' && !opts.suspense) { - const moduleIds = opts.webpack ? opts.webpack() : opts.modules + // require.resolveWeak check is needed for environments that don't have it available like Jest + const moduleIds = + opts.webpack && typeof require.resolveWeak === 'function' + ? opts.webpack() + : opts.modules if (moduleIds) { READY_INITIALIZERS.push((ids) => { for (const moduleId of moduleIds) { diff --git a/test/production/next/jest/index.test.ts b/test/production/next/jest/index.test.ts index dd1ae29da5381..6d110b9106977 100644 --- a/test/production/next/jest/index.test.ts +++ b/test/production/next/jest/index.test.ts @@ -8,9 +8,23 @@ describe('next/jest', () => { beforeAll(async () => { next = await createNext({ files: { + 'components/comp.js': ` + export default function Comp() { + return

Hello Dynamic

; + } + `, 'pages/index.js': ` + import dynamic from "next/dynamic"; + + const Comp = dynamic(() => import("../components/comp"), { + loading: () =>

Loading...

, + }); + export default function Page() { - return

hello world

+ return <> + +

hello world

+ } `, 'jest.config.js': ` @@ -27,11 +41,39 @@ describe('next/jest', () => { // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work moduleDirectories: ['node_modules', '/'], testEnvironment: 'jest-environment-jsdom', + setupFilesAfterEnv: ['/jest.setup.js'], + transform: { + // Use babel-jest to transpile tests with the next/babel preset + // https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object + '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }], + }, } // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async module.exports = createJestConfig(customJestConfig) `, + 'jest.setup.js': ` + // Learn more: https://github.com/testing-library/jest-dom + import '@testing-library/jest-dom/extend-expect' + `, + 'test/dynamic.test.js': ` + import { render, screen, act } from "@testing-library/react"; + import Home from "../pages/index"; + + describe("Home", () => { + it("renders a heading", () => { + act(() => { + render(); + + const heading = screen.getByRole("heading", { + name: /Loading/i, + }); + + expect(heading).toBeInTheDocument(); + }); + }); + }); + `, 'test/mock.test.js': ` import router from 'next/router' @@ -56,10 +98,15 @@ describe('next/jest', () => { }, dependencies: { jest: '27.4.7', + '@testing-library/jest-dom': '5.16.1', + '@testing-library/react': '12.1.2', + '@testing-library/user-event': '13.5.0', }, packageJson: { scripts: { - build: 'next build && yarn jest test/mock.test.js', + // Runs jest and bails if jest fails + build: + 'next build && yarn jest test/mock.test.js test/dynamic.test.js', }, }, buildCommand: `yarn build`,