Skip to content

Commit d7b92a1

Browse files
fix: generate handlers with correct site root (#235)
* fix: generate handlers dynamically * fix: chdir into site root * chore: handler fixes * fix: copy api handler * fix: only clear require cache in local dev * chore: changes from review Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
1 parent c1b134d commit d7b92a1

File tree

13 files changed

+238
-364
lines changed

13 files changed

+238
-364
lines changed

.eslintrc.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module.exports = {
99
'node/no-unsupported-features/es-syntax': 'off',
1010
// This is a duplicate of `import/no-duplicates` but can handle "import type"
1111
'no-duplicate-imports': 'off',
12+
'max-depth': ['error', 4],
1213
},
1314
env: {
1415
jest: true,
@@ -37,6 +38,9 @@ module.exports = {
3738
'node/no-unpublished-require': 'off',
3839
'node/no-missing-require': 'off',
3940
'max-lines': 'off',
41+
complexity: 'off',
42+
'max-statements': 'off',
43+
'node/prefer-global/process': 'off',
4044
'unicorn/filename-case': 'off',
4145
},
4246
},

plugin/package-lock.json

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"linkfs": "^2.1.0",
5151
"multer": "^1.4.2",
5252
"node-fetch": "^2.6.1",
53+
"pathe": "^0.2.0",
5354
"tempy": "^1.0.0"
5455
},
5556
"devDependencies": {
@@ -64,6 +65,7 @@
6465
},
6566
"peerDependencies": {
6667
"@gatsbyjs/reach-router": "^1.3.6",
68+
"common-tags": "^1.8.2",
6769
"execa": "^5.0.0"
6870
}
6971
}

plugin/src/helpers/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export function mutateConfig({
112112
path.posix.join(CACHE_DIR, 'page-ssr', '**'),
113113
],
114114
external_node_modules: ['msgpackr-extract'],
115+
node_bundler: 'esbuild',
115116
}
116117

117118
netlifyConfig.functions.__ssr = { ...netlifyConfig.functions.__dsg }

plugin/src/helpers/functions.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import process from 'process'
2+
3+
import { NetlifyPluginConstants } from '@netlify/build'
4+
import { copy, copyFile, ensureDir, writeFile } from 'fs-extra'
5+
import { resolve, join, relative } from 'pathe'
6+
7+
import { makeHandler } from '../templates/handlers'
8+
9+
const writeFunction = async ({
10+
renderMode,
11+
handlerName,
12+
appDir,
13+
functionsSrc,
14+
}) => {
15+
const source = makeHandler(appDir, renderMode)
16+
await ensureDir(join(functionsSrc, handlerName))
17+
await writeFile(join(functionsSrc, handlerName, `${handlerName}.js`), source)
18+
await copyFile(
19+
join(__dirname, '..', '..', 'lib', 'templates', 'utils.js'),
20+
join(functionsSrc, handlerName, 'utils.js'),
21+
)
22+
}
23+
24+
export const writeFunctions = async ({
25+
INTERNAL_FUNCTIONS_SRC,
26+
PUBLISH_DIR,
27+
}: NetlifyPluginConstants): Promise<void> => {
28+
const siteRoot = resolve(process.cwd(), PUBLISH_DIR, '..')
29+
const functionDir = join(process.cwd(), INTERNAL_FUNCTIONS_SRC, '__api')
30+
const appDir = relative(functionDir, siteRoot)
31+
32+
await writeFunction({
33+
renderMode: 'SSR',
34+
handlerName: '__ssr',
35+
appDir,
36+
functionsSrc: INTERNAL_FUNCTIONS_SRC,
37+
})
38+
39+
await writeFunction({
40+
renderMode: 'DSG',
41+
handlerName: '__dsg',
42+
appDir,
43+
functionsSrc: INTERNAL_FUNCTIONS_SRC,
44+
})
45+
46+
await copy(
47+
join(__dirname, '..', '..', 'lib', 'templates', 'api'),
48+
functionDir,
49+
)
50+
}

plugin/src/index.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import fs from 'fs-extra'
55

66
import { normalizedCacheDir, restoreCache, saveCache } from './helpers/cache'
77
import { checkGatsbyConfig, mutateConfig, spliceConfig } from './helpers/config'
8+
import { writeFunctions } from './helpers/functions'
89

910
// eslint-disable-next-line no-template-curly-in-string
1011
const lmdbCacheString = 'process.cwd(), `.cache/${cacheDbFile}`'
@@ -45,34 +46,23 @@ export async function onPreBuild({
4546
checkGatsbyConfig({ utils, netlifyConfig })
4647
}
4748

48-
export async function onBuild({
49-
constants: {
49+
export async function onBuild({ constants, netlifyConfig }): Promise<void> {
50+
const {
5051
PUBLISH_DIR,
5152
FUNCTIONS_SRC = DEFAULT_FUNCTIONS_SRC,
5253
INTERNAL_FUNCTIONS_SRC,
53-
},
54-
netlifyConfig,
55-
}): Promise<void> {
54+
} = constants
5655
const CACHE_DIR = normalizedCacheDir(PUBLISH_DIR)
5756
const compiledFunctionsDir = path.join(CACHE_DIR, '/functions')
5857
// eslint-disable-next-line node/no-sync
5958
if (!fs.existsSync(compiledFunctionsDir)) {
6059
return
6160
}
6261

63-
const functionsSrcDir = INTERNAL_FUNCTIONS_SRC || FUNCTIONS_SRC
62+
await writeFunctions(constants)
6463

6564
// copying Netlify wrapper function into functions directory
6665

67-
await Promise.all(
68-
['api', 'dsg', 'ssr'].map((func) =>
69-
fs.copy(
70-
path.join(__dirname, '..', 'src', 'templates', func),
71-
path.join(functionsSrcDir, `__${func}`),
72-
),
73-
),
74-
)
75-
7666
if (
7767
INTERNAL_FUNCTIONS_SRC &&
7868
// eslint-disable-next-line node/no-sync

plugin/src/templates/api/gatsbyFunction.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ type MulterRes = Parameters<typeof parseForm>[1]
1919
/**
2020
* Execute a Gatsby function
2121
*/
22-
// eslint-disable-next-line complexity, max-statements
2322
export async function gatsbyFunction(
2423
req: AugmentedGatsbyFunctionRequest,
2524
res: AugmentedGatsbyFunctionResponse,
@@ -70,7 +69,7 @@ export async function gatsbyFunction(
7069
const matchResult = reachMatch(func.matchPath, pathFragment)
7170
if (matchResult) {
7271
req.params = matchResult.params
73-
// eslint-disable-next-line max-depth
72+
7473
if (req.params[`*`]) {
7574
// Backwards compatability for v3
7675
// TODO remove in v5
@@ -112,7 +111,11 @@ export async function gatsbyFunction(
112111
}
113112

114113
try {
115-
// Make sure it's hot and fresh from the filesystem
114+
if (process.env.NETLIFY_LOCAL) {
115+
// Make sure it's hot and fresh from the filesystem
116+
delete require.cache[require.resolve(pathToFunction)]
117+
}
118+
116119
const fn = require(pathToFunction)
117120

118121
const fnToExecute = (fn && fn.default) || fn
@@ -121,7 +124,6 @@ export async function gatsbyFunction(
121124
} catch (error) {
122125
console.error(error)
123126
// Don't send the error if that would cause another error.
124-
// eslint-disable-next-line max-depth
125127
if (!res.headersSent) {
126128
res
127129
.status(500)

plugin/src/templates/api/utils.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ export interface AugmentedGatsbyFunctionRequest extends GatsbyFunctionRequest {
3434
// Based on API Gateway Lambda Compat
3535
// Source: https://github.com/serverless-nextjs/serverless-next.js/blob/master/packages/compat-layers/apigw-lambda-compat/lib/compatLayer.js
3636

37-
// eslint-disable-next-line complexity, max-statements
3837
export const createRequestObject = ({
3938
event,
4039
context,
@@ -118,7 +117,7 @@ interface IntermediateHandlerResponse
118117
// Based on API Gateway Lambda Compat
119118
// Source: https://github.com/serverless-nextjs/serverless-next.js/blob/master/packages/compat-layers/apigw-lambda-compat/lib/compatLayer.js
120119

121-
// eslint-disable-next-line max-statements, max-lines-per-function
120+
// eslint-disable-next-line max-lines-per-function
122121
export const createResponseObject = ({ onResEnd }) => {
123122
const response: IntermediateHandlerResponse = {
124123
isBase64Encoded: true,
@@ -170,7 +169,6 @@ export const createResponseObject = ({ onResEnd }) => {
170169
res.getHeader = (name) => res.headers[name.toLowerCase()]
171170
res.getHeaders = () => res.headers
172171
res.hasHeader = (name) => Boolean(res.getHeader(name))
173-
// eslint-disable-next-line complexity
174172
res.end = (text) => {
175173
if (text) res.write(text)
176174
if (!res.statusCode) {
@@ -247,7 +245,6 @@ export const createResponseObject = ({ onResEnd }) => {
247245
* During `netlify dev` we proxy requests to the `gatsby develop` server instead of
248246
* serving them ourselves.
249247
*/
250-
// eslint-disable-next-line max-statements
251248
export const proxyRequest = async (event: HandlerEvent, res) => {
252249
// todo: get this from config
253250
const port = `8000`

plugin/src/templates/dsg/__dsg.ts

Lines changed: 0 additions & 119 deletions
This file was deleted.

0 commit comments

Comments
 (0)