From 9bf3b7f0f0dde989b3b75a4d911c681ffcf75bd8 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Fri, 5 Jan 2024 12:19:38 +0100 Subject: [PATCH 1/5] chore: unpin netlify-cli used for tests --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5122e5bb..f89978b8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,7 +29,7 @@ jobs: key: ubuntu-build-${{ env.cache-name }}-${{ hashFiles('plugin/test/fixtures/**/package.json') }}-node-modules - - run: npm install -g netlify-cli@17.6.0 + - run: npm install -g netlify-cli - run: npm ci - run: cd plugin && npm ci && npm run build - run: npm test From 5ecbd48c12376298a4fa726476371b11fa797580 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Fri, 5 Jan 2024 12:35:00 +0100 Subject: [PATCH 2/5] fix: clear redirects/rewrites produced by previous builds in ntl dev --- plugin/src/helpers/config.ts | 35 ++++++++++++++++++++++++++++++++++- plugin/src/index.ts | 5 +++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/plugin/src/helpers/config.ts b/plugin/src/helpers/config.ts index 43aab3bd..e4fc3646 100644 --- a/plugin/src/helpers/config.ts +++ b/plugin/src/helpers/config.ts @@ -196,6 +196,40 @@ export async function createMetadataFileAndCopyDatastore( await writeJSON(`${cacheDir}/dataMetadata.json`, payload) } +export async function modifyConfigDev({ + netlifyConfig, +}: { + netlifyConfig: NetlifyConfig +}): Promise { + const redirectsFileName = join(netlifyConfig.build.publish, '_redirects') + // removing redirects that possibly were added for builds previously + // DSG/SSR and API is fully handled by gatsby dev server + await spliceConfig({ + startMarker: '# @netlify/plugin-gatsby redirects start', + endMarker: '# @netlify/plugin-gatsby redirects end', + contents: '', + fileName: redirectsFileName, + }) + // this is a bit of a hack - gatsby-plugin-netlify appends redirects before @netlify/plugin-gatsby + // so we use gatsby-plugin-netlify marker as start and @netlify/plugin-gatsby start marker as end + await spliceConfig({ + startMarker: '## Created with gatsby-plugin-netlify', + endMarker: '# @netlify/plugin-gatsby redirects start', + contents: '', + fileName: redirectsFileName, + }) + // this removes redirects produced by adapters in newer gatsby versions + // while build plugin doesn't do any work during builds when adapters are used + // adapters don't have hooks for `develop` so they can't clean their redirects + // so build plugin is handling that as it still runs (just skips most of the work) + await spliceConfig({ + startMarker: '# gatsby-adapter-netlify start', + endMarker: '# gatsby-adapter-netlify end', + contents: '', + fileName: redirectsFileName, + }) +} + export async function modifyConfig({ netlifyConfig, cacheDir, @@ -208,7 +242,6 @@ export async function modifyConfig({ mutateConfig({ netlifyConfig, cacheDir, neededFunctions }) if (neededFunctions.includes('API')) { - // Editing _redirects so it works with ntl dev await spliceConfig({ startMarker: '# @netlify/plugin-gatsby redirects start', endMarker: '# @netlify/plugin-gatsby redirects end', diff --git a/plugin/src/index.ts b/plugin/src/index.ts index 219c90e6..21f8d921 100644 --- a/plugin/src/index.ts +++ b/plugin/src/index.ts @@ -13,6 +13,7 @@ import { checkConfig, getNeededFunctions, modifyConfig, + modifyConfigDev, shouldSkipBundlingDatastore, shouldSkip, checkNetlifyImageCdn, @@ -47,6 +48,10 @@ export async function onPreBuild({ await checkNetlifyImageCdn({ netlifyConfig }) } +export async function onDev({ netlifyConfig }): Promise { + await modifyConfigDev({ netlifyConfig }) +} + export async function onBuild({ constants, netlifyConfig, From fe67398d2ad93c1aeea8bcb13c9a0a1466e2fd5b Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Fri, 5 Jan 2024 13:12:58 +0100 Subject: [PATCH 3/5] test: adjust content-type assertions --- .../v5/with-adapters/e2e-tests/test-helpers.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugin/test/fixtures/v5/with-adapters/e2e-tests/test-helpers.js b/plugin/test/fixtures/v5/with-adapters/e2e-tests/test-helpers.js index 30b4d1ea..426ba8fb 100644 --- a/plugin/test/fixtures/v5/with-adapters/e2e-tests/test-helpers.js +++ b/plugin/test/fixtures/v5/with-adapters/e2e-tests/test-helpers.js @@ -117,7 +117,9 @@ exports.runTests = function runTests(env, host) { expect(result).toEqual({ amIJSON: true, }) - expect(res.headers.get('content-type')).toEqual('application/json') + expect(res.headers.get('content-type')).toEqual( + 'application/json; charset=utf-8', + ) }) test(`returns json correctly via send`, async () => { const res = await fetchTwice(`${host}/api/i-am-json-too`) @@ -126,14 +128,18 @@ exports.runTests = function runTests(env, host) { expect(result).toEqual({ amIJSON: true, }) - expect(res.headers.get('content-type')).toEqual('application/json') + expect(res.headers.get('content-type')).toEqual( + 'application/json; charset=utf-8', + ) }) test(`returns boolean correctly via send`, async () => { const res = await fetchTwice(`${host}/api/i-am-false`) const result = await res.json() expect(result).toEqual(false) - expect(res.headers.get('content-type')).toEqual('application/json') + expect(res.headers.get('content-type')).toEqual( + 'application/json; charset=utf-8', + ) }) test(`returns status correctly via send`, async () => { const res = await fetchTwice(`${host}/api/i-am-status`) From ebd5bd451c8a5f9c9da6b7fe9a8f788b5ceedd98 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Fri, 5 Jan 2024 13:51:20 +0100 Subject: [PATCH 4/5] fix: create Netlify Functions in dev --- plugin/src/helpers/config.ts | 70 +++++++++++++++++------------------- plugin/src/index.ts | 25 ++++++++++--- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/plugin/src/helpers/config.ts b/plugin/src/helpers/config.ts index e4fc3646..6cdbe779 100644 --- a/plugin/src/helpers/config.ts +++ b/plugin/src/helpers/config.ts @@ -196,57 +196,51 @@ export async function createMetadataFileAndCopyDatastore( await writeJSON(`${cacheDir}/dataMetadata.json`, payload) } -export async function modifyConfigDev({ +export async function modifyConfig({ netlifyConfig, + cacheDir, + neededFunctions, + isDev, }: { netlifyConfig: NetlifyConfig + cacheDir: string + neededFunctions: FunctionList + isDev?: boolean }): Promise { + mutateConfig({ netlifyConfig, cacheDir, neededFunctions }) + const redirectsFileName = join(netlifyConfig.build.publish, '_redirects') - // removing redirects that possibly were added for builds previously - // DSG/SSR and API is fully handled by gatsby dev server + await spliceConfig({ startMarker: '# @netlify/plugin-gatsby redirects start', endMarker: '# @netlify/plugin-gatsby redirects end', - contents: '', - fileName: redirectsFileName, - }) - // this is a bit of a hack - gatsby-plugin-netlify appends redirects before @netlify/plugin-gatsby - // so we use gatsby-plugin-netlify marker as start and @netlify/plugin-gatsby start marker as end - await spliceConfig({ - startMarker: '## Created with gatsby-plugin-netlify', - endMarker: '# @netlify/plugin-gatsby redirects start', - contents: '', - fileName: redirectsFileName, - }) - // this removes redirects produced by adapters in newer gatsby versions - // while build plugin doesn't do any work during builds when adapters are used - // adapters don't have hooks for `develop` so they can't clean their redirects - // so build plugin is handling that as it still runs (just skips most of the work) - await spliceConfig({ - startMarker: '# gatsby-adapter-netlify start', - endMarker: '# gatsby-adapter-netlify end', - contents: '', + contents: neededFunctions.includes('API') + ? '/api/* /.netlify/functions/__api 200' + : '', fileName: redirectsFileName, }) -} -export async function modifyConfig({ - netlifyConfig, - cacheDir, - neededFunctions, -}: { - netlifyConfig: NetlifyConfig - cacheDir: string - neededFunctions: FunctionList -}): Promise { - mutateConfig({ netlifyConfig, cacheDir, neededFunctions }) + if (isDev) { + // removing redirects that possibly were added for builds previously + // DSG/SSR is fully handled by gatsby dev server and is not even produced in dev - if (neededFunctions.includes('API')) { + // this is a bit of a hack - gatsby-plugin-netlify appends redirects before @netlify/plugin-gatsby + // so we use gatsby-plugin-netlify marker as start and @netlify/plugin-gatsby start marker as end + await spliceConfig({ + startMarker: '## Created with gatsby-plugin-netlify', + endMarker: '# @netlify/plugin-gatsby redirects start', + contents: '', + fileName: redirectsFileName, + }) + // this removes redirects produced by adapters in newer gatsby versions + // while build plugin doesn't do any work during builds when adapters are used + // adapters don't have hooks for `develop` so they can't clean their redirects + // so build plugin is handling that as it still runs (just skips most of the work) await spliceConfig({ - startMarker: '# @netlify/plugin-gatsby redirects start', - endMarker: '# @netlify/plugin-gatsby redirects end', - contents: '/api/* /.netlify/functions/__api 200', - fileName: join(netlifyConfig.build.publish, '_redirects'), + startMarker: '# gatsby-adapter-netlify start', + endMarker: '# gatsby-adapter-netlify end', + contents: '', + fileName: redirectsFileName, }) } } diff --git a/plugin/src/index.ts b/plugin/src/index.ts index 21f8d921..030bbabf 100644 --- a/plugin/src/index.ts +++ b/plugin/src/index.ts @@ -13,7 +13,6 @@ import { checkConfig, getNeededFunctions, modifyConfig, - modifyConfigDev, shouldSkipBundlingDatastore, shouldSkip, checkNetlifyImageCdn, @@ -48,8 +47,26 @@ export async function onPreBuild({ await checkNetlifyImageCdn({ netlifyConfig }) } -export async function onDev({ netlifyConfig }): Promise { - await modifyConfigDev({ netlifyConfig }) +export async function onDev({ + netlifyConfig, + constants, +}: NetlifyPluginOptions): Promise { + // eslint-disable-next-line no-param-reassign + netlifyConfig.build.environment.GATSBY_PRECOMPILE_DEVELOP_FUNCTIONS = `true` + + const { PUBLISH_DIR } = constants + + const cacheDir = normalizedCacheDir(PUBLISH_DIR) + + const neededFunctionsForBuild = await getNeededFunctions(cacheDir) + // DSG/SSR engine is not produced for dev so we are filtering them out + const neededFunctions = neededFunctionsForBuild.filter( + (neededFunction) => neededFunction !== 'DSG' && neededFunction !== 'SSR', + ) + + await writeFunctions({ constants, netlifyConfig, neededFunctions }) + + await modifyConfig({ netlifyConfig, cacheDir, neededFunctions, isDev: true }) } export async function onBuild({ @@ -91,7 +108,7 @@ The plugin no longer uses this and it should be deleted to avoid conflicts.\n`) await writeFunctions({ constants, netlifyConfig, neededFunctions }) - await modifyConfig({ netlifyConfig, cacheDir, neededFunctions }) + await modifyConfig({ netlifyConfig, cacheDir, neededFunctions, isDev: false }) await modifyFiles({ netlifyConfig, neededFunctions }) } From 84d868ed96e228e3a8a8d53e634c1a63031b6cf4 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Fri, 5 Jan 2024 13:51:41 +0100 Subject: [PATCH 5/5] Revert "test: adjust content-type assertions" This reverts commit fe67398d2ad93c1aeea8bcb13c9a0a1466e2fd5b. --- .../v5/with-adapters/e2e-tests/test-helpers.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/plugin/test/fixtures/v5/with-adapters/e2e-tests/test-helpers.js b/plugin/test/fixtures/v5/with-adapters/e2e-tests/test-helpers.js index 426ba8fb..30b4d1ea 100644 --- a/plugin/test/fixtures/v5/with-adapters/e2e-tests/test-helpers.js +++ b/plugin/test/fixtures/v5/with-adapters/e2e-tests/test-helpers.js @@ -117,9 +117,7 @@ exports.runTests = function runTests(env, host) { expect(result).toEqual({ amIJSON: true, }) - expect(res.headers.get('content-type')).toEqual( - 'application/json; charset=utf-8', - ) + expect(res.headers.get('content-type')).toEqual('application/json') }) test(`returns json correctly via send`, async () => { const res = await fetchTwice(`${host}/api/i-am-json-too`) @@ -128,18 +126,14 @@ exports.runTests = function runTests(env, host) { expect(result).toEqual({ amIJSON: true, }) - expect(res.headers.get('content-type')).toEqual( - 'application/json; charset=utf-8', - ) + expect(res.headers.get('content-type')).toEqual('application/json') }) test(`returns boolean correctly via send`, async () => { const res = await fetchTwice(`${host}/api/i-am-false`) const result = await res.json() expect(result).toEqual(false) - expect(res.headers.get('content-type')).toEqual( - 'application/json; charset=utf-8', - ) + expect(res.headers.get('content-type')).toEqual('application/json') }) test(`returns status correctly via send`, async () => { const res = await fetchTwice(`${host}/api/i-am-status`)