From 2ba6db65e2b16395bb76c054baa81227db65317a Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 25 Mar 2020 13:57:14 -0500 Subject: [PATCH] Update to prevent re-using workers for getStaticPaths in dev mode (#11347) --- packages/next/server/static-paths-worker.ts | 17 +++++------ .../prerender/pages/blog/[post]/index.js | 1 + test/integration/prerender/test/index.test.js | 29 ++++++++++++++++++- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/packages/next/server/static-paths-worker.ts b/packages/next/server/static-paths-worker.ts index 3757117f429742e..f0ff595f0b9d97f 100644 --- a/packages/next/server/static-paths-worker.ts +++ b/packages/next/server/static-paths-worker.ts @@ -1,8 +1,7 @@ import { buildStaticPaths } from '../build/utils' import { loadComponents } from '../next-server/server/load-components' -// store initial require modules so we don't clear them below -const initialCache = new Set(Object.keys(require.cache)) +let workerWasUsed = false // we call getStaticPaths in a separate process to ensure // side-effects aren't relied on in dev that will break @@ -13,14 +12,11 @@ export async function loadStaticPaths( pathname: string, serverless: boolean ) { - // we need to clear any modules manually here since the - // require-cache-hot-loader doesn't affect require cache here - // since we're in a separate process - Object.keys(require.cache).forEach(mod => { - if (!initialCache.has(mod)) { - delete require.cache[mod] - } - }) + // we only want to use each worker once to prevent any invalid + // caches + if (workerWasUsed) { + process.exit(1) + } const components = await loadComponents( distDir, @@ -37,5 +33,6 @@ export async function loadStaticPaths( ) } + workerWasUsed = true return buildStaticPaths(pathname, components.getStaticPaths) } diff --git a/test/integration/prerender/pages/blog/[post]/index.js b/test/integration/prerender/pages/blog/[post]/index.js index 8cae293f7a70618..ee32341ab1f3f5b 100644 --- a/test/integration/prerender/pages/blog/[post]/index.js +++ b/test/integration/prerender/pages/blog/[post]/index.js @@ -1,6 +1,7 @@ import React from 'react' import Link from 'next/link' import { useRouter } from 'next/router' +import 'firebase/firestore' export async function getStaticPaths() { return { diff --git a/test/integration/prerender/test/index.test.js b/test/integration/prerender/test/index.test.js index 13cff47a1ffc1c6..923c2d65558b945 100644 --- a/test/integration/prerender/test/index.test.js +++ b/test/integration/prerender/test/index.test.js @@ -1065,6 +1065,16 @@ describe('SSG Prerender', () => { await killApp(app) }) + it('should work with firebase import and getStaticPaths', async () => { + const html = await renderViaHTTP(appPort, '/blog/post-1') + expect(html).toContain('post-1') + expect(html).not.toContain('Error: Failed to load') + + const html2 = await renderViaHTTP(appPort, '/blog/post-1') + expect(html2).toContain('post-1') + expect(html2).not.toContain('Error: Failed to load') + }) + it('should not cache getStaticPaths errors', async () => { const errMsg = /The `fallback` key must be returned from getStaticPaths/ await check(() => renderViaHTTP(appPort, '/blog/post-1'), /post-1/) @@ -1088,7 +1098,21 @@ describe('SSG Prerender', () => { }) describe('serverless mode', () => { + const blogPagePath = join(appDir, 'pages/blog/[post]/index.js') + let origBlogPageContent + beforeAll(async () => { + // remove firebase import since it breaks in legacy serverless mode + origBlogPageContent = await fs.readFile(blogPagePath, 'utf8') + + await fs.writeFile( + blogPagePath, + origBlogPageContent.replace( + `import 'firebase/firestore'`, + `// import 'firebase/firestore'` + ) + ) + await fs.writeFile( nextConfig, `module.exports = { target: 'serverless' }`, @@ -1106,7 +1130,10 @@ describe('SSG Prerender', () => { distPagesDir = join(appDir, '.next/serverless/pages') buildId = await fs.readFile(join(appDir, '.next/BUILD_ID'), 'utf8') }) - afterAll(() => killApp(app)) + afterAll(async () => { + await fs.writeFile(blogPagePath, origBlogPageContent) + await killApp(app) + }) it('renders data correctly', async () => { const port = await findPort()