From 40329a70a5b4680e71c5ee1d9a7e59b10d80f113 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Tue, 8 Feb 2022 15:02:53 +0100 Subject: [PATCH] Add check for resolveWeak to next/dynamic (#33908) Fixes #33476 I've added the test for this but it passes either way, even when the change to loadable.js is not made. On the reproduction I was able to reproduce it consistently and it's fixed with this change. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `yarn lint` --- packages/next/shared/lib/loadable.js | 6 ++- test/production/next/jest/index.test.ts | 51 ++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 3 deletions(-) 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`,