diff --git a/src/__tests__/gatsby-node.ts b/src/__tests__/gatsby-node.ts index 101297e7..f90d65e8 100644 --- a/src/__tests__/gatsby-node.ts +++ b/src/__tests__/gatsby-node.ts @@ -1,3 +1,4 @@ +/* eslint-disable max-lines-per-function */ jest.mock('../plugin-data', () => ({ __esModule: true, default: jest.fn().mockReturnValue({ @@ -14,10 +15,12 @@ jest.mock('fs-extra', () => ({ existsSync: jest.fn(), readFile: jest.fn(), writeFile: jest.fn(), + writeJson: jest.fn(), + remove: jest.fn(), })) // Importing writeFile here gives us access to the mocked method to assert the correct content is written to the file within test cases -import { writeFile } from 'fs-extra' +import { writeFile, writeJson, remove } from 'fs-extra' import { testPluginOptionsSchema } from 'gatsby-plugin-utils' import { pluginOptionsSchema, onPostBuild } from '../gatsby-node' @@ -67,12 +70,12 @@ describe(`gatsby-node.js`, () => { }) describe('onPostBuild', () => { - let store = {} const reporter = { info: jest.fn(), } - beforeEach(() => { - store = { + + it('creates redirects for SSR and DSG pages in format Netlify expects', async () => { + const store = { getState: jest.fn().mockReturnValue({ redirects: [], pages: [ @@ -89,13 +92,6 @@ describe(`gatsby-node.js`, () => { program: { directory: '' }, }), } - }) - - afterEach(() => { - jest.resetAllMocks() - }) - - it('creates redirects for SSR and DSG pages in format Netlify expects', async () => { const expectedValue = [ '', '## Created with gatsby-plugin-netlify', @@ -106,7 +102,55 @@ describe(`gatsby-node.js`, () => { ].join(`\n`) await onPostBuild({ store, pathPrefix: '', reporter }, {}) - expect(writeFile).toHaveBeenCalledWith('mock-file-path', expectedValue) + expect(writeFile).toHaveBeenLastCalledWith('mock-file-path', expectedValue) + }) + + it('creates skip file for unneeded function bundles', async () => { + const store = { + getState: jest.fn().mockReturnValue({ + redirects: [], + pages: [ + { + mode: 'DSG', + path: 'some/other/path', + }, + ], + functions: [], + program: { directory: '' }, + }), + } + const expectedValue = { + API: false, + SSR: false, + DSG: true, + } + + await onPostBuild({ store, pathPrefix: '', reporter }, {}) + expect(writeJson).toHaveBeenLastCalledWith('.cache/.nf-skip-gatsby-functions', expectedValue) + }) + + it('removes skip file when all function bundles needed', async () => { + const store = { + getState: jest.fn().mockReturnValue({ + redirects: [], + pages: [ + { + mode: 'SSR', + path: 'some/path', + }, + { + mode: 'DSG', + path: 'some/other/path', + }, + ], + functions: [true], + program: { directory: '' }, + }), + } + + await onPostBuild({ store, pathPrefix: '', reporter }, {}) + expect(remove).toHaveBeenCalled() }) }) }) +/* eslint-enable max-lines-per-function */ diff --git a/src/gatsby-node.ts b/src/gatsby-node.ts index 00f87a53..e022c578 100644 --- a/src/gatsby-node.ts +++ b/src/gatsby-node.ts @@ -1,7 +1,7 @@ // https://www.netlify.com/docs/headers-and-basic-auth/ import { join } from 'path' -import { writeFile } from 'fs-extra' +import { writeJson, remove } from 'fs-extra' import { generatePageDataPath } from 'gatsby-core-utils' import WebpackAssetsManifest from 'webpack-assets-manifest' @@ -72,7 +72,11 @@ export const onPostBuild = async ({ store, pathPrefix, reporter }: any, userPlug let count = 0 const rewrites: any = [] - let needsFunctions = functions.length !== 0 + const neededFunctions = { + API: functions.length !== 0, + SSR: false, + DSG: false, + } ;[...pages.values()].forEach((page) => { const { mode, matchPath, path } = page @@ -80,7 +84,7 @@ export const onPostBuild = async ({ store, pathPrefix, reporter }: any, userPlug const matchPathIsNotPath = matchPath && matchPath !== path if (mode === `SSR` || mode === `DSG`) { - needsFunctions = true + neededFunctions[mode] = true const fromPath = matchPathClean ?? path const toPath = mode === `SSR` ? `/.netlify/functions/__ssr` : `/.netlify/functions/__dsg` count++ @@ -103,12 +107,13 @@ export const onPostBuild = async ({ store, pathPrefix, reporter }: any, userPlug }) reporter.info(`[gatsby-plugin-netlify] Created ${count} SSR/DSG redirect${count === 1 ? `` : `s`}...`) - if (!needsFunctions) { - reporter.info(`[gatsby-plugin-netlify] No Netlify functions needed. Skipping...`) - await writeFile(join(program.directory, `.cache`, `.nf-skip-gatsby-functions`), ``) - } + const skipFilePath = join(program.directory, `.cache`, `.nf-skip-gatsby-functions`) + const generateSkipFile = Object.values(neededFunctions).includes(false) + ? writeJson(skipFilePath, neededFunctions) + : remove(skipFilePath) await Promise.all([ + generateSkipFile, buildHeadersProgram(pluginData, pluginOptions, reporter), createRedirects(pluginData, redirects, rewrites), ])