Skip to content

Commit 770ae06

Browse files
refactor: Drop netlify-lambda, use Vite middleware for Netlify functions (#1108)
* refactor: Drop netlify-lambda, use Vite middleware for Netlify functions Co-authored-by: Marvin Hagemeister <hello@marvinh.dev> * feat: Add middleware plugin for serving prerendered HTML --------- Co-authored-by: Marvin Hagemeister <hello@marvinh.dev>
1 parent 68208e4 commit 770ae06

7 files changed

Lines changed: 4476 additions & 13322 deletions

File tree

package-lock.json

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

package.json

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,9 @@
77
"node": ">=18"
88
},
99
"scripts": {
10-
"dev": "concurrently \"npm run dev:client\" \"npm run dev:lambda\"",
11-
"dev:client": "vite --port 8080",
12-
"dev:lambda": "netlify-lambda serve src/lambda",
13-
"start": "npm run -s server",
14-
"prestart": "npm run -s build",
15-
"server": "superstatic build -p ${PORT:-8080} --host 0.0.0.0 --compression -c '{\"headers\":[{\"source\":\"**\",\"headers\":[{\"key\":\"Cache-Control\",\"value\":\"max-age=31536000\"}]}]}'",
16-
"build": "netlify-lambda build src/lambda && vite build",
10+
"dev": "vite --port 8080",
11+
"server": "vite preview --port 8080",
12+
"build": "vite build",
1713
"lint": "eslint src test",
1814
"format": "prettier --write \"{src,test}/**/*.{css,js,json}\"",
1915
"prepare": "husky install",
@@ -63,11 +59,9 @@
6359
"feed": "^4.2.2",
6460
"husky": "^8.0.3",
6561
"lint-staged": "^15.2.0",
66-
"netlify-lambda": "^2.0.16",
6762
"patch-package": "^8.0.0",
6863
"prettier": "^1.19.1",
6964
"rimraf": "^5.0.5",
70-
"superstatic": "^9.0.3",
7165
"vite": "^5.0.11",
7266
"vite-plugin-static-copy": "1.0.2"
7367
},

patches/netlify-lambda+2.0.16.patch

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

src/lambda/release.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ export const handler = async event => {
1010
url
1111
}),
1212
headers: {
13-
'Cache-Control': 'public, max-age=3600, stale-if-error=86400',
14-
'Access-Control-Allow-Origin': 'http://localhost:8080'
13+
'Content-Type': 'application/json',
14+
'Cache-Control': 'public, max-age=3600, stale-if-error=86400'
1515
}
1616
};
1717
};

src/lambda/repo.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ export const handler = async event => {
66
statusCode: 200,
77
body: JSON.stringify(result),
88
headers: {
9-
'Cache-Control': 'public, s-maxage=1800',
10-
'Access-Control-Allow-Origin': 'http://localhost:8080'
9+
'Content-Type': 'application/json',
10+
'Cache-Control': 'public, max-age=3600, stale-if-error=86400'
1111
}
1212
};
1313
};

src/lib/github.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ export const fallbackData = {
1515
preactStargazers: 35783
1616
};
1717

18-
const baseUrl =
19-
process.env.NODE_ENV === 'production'
20-
? '/.netlify/functions/'
21-
: 'http://localhost:9000/.netlify/functions/';
18+
const baseUrl = '/.netlify/functions/';
2219

2320
export const repoInfo = repo =>
2421
fetch(`${baseUrl}repo?repo=${repo}`, { credentials: 'omit' })

vite.config.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import preact from '@preact/preset-vite';
33
import { viteStaticCopy } from 'vite-plugin-static-copy';
44
import replace from '@rollup/plugin-replace';
55
import yaml from 'yaml';
6+
import path from 'path';
7+
import { promises as fs } from 'fs';
68
import { Feed } from 'feed';
79
import config from './src/config.json';
810

@@ -79,10 +81,96 @@ export default defineConfig({
7981
reloadPageOnChange: true
8082
}
8183
}),
84+
netlifyPlugin(),
85+
servePrerenderedHTML(),
8286
rssFeedPlugin()
8387
]
8488
});
8589

90+
/**
91+
* @returns {import('vite').Plugin}
92+
*/
93+
function servePrerenderedHTML() {
94+
let outDir;
95+
96+
return {
97+
name: 'serve-prerendered-html',
98+
config(config) {
99+
outDir = path.join(__dirname, config.build.outDir);
100+
},
101+
configurePreviewServer(server) {
102+
server.middlewares.use(async (req, _res, next) => {
103+
if (!req.url) return next();
104+
105+
const url = new URL(req.url, `http://${req.headers.host}`);
106+
// If URL has a file extension, bail
107+
if (url.pathname != url.pathname.split('.').pop()) return next();
108+
109+
const file = path.join(
110+
outDir,
111+
url.pathname
112+
.split(path.posix.sep)
113+
.join(path.sep),
114+
'index.html'
115+
);
116+
117+
try {
118+
await fs.access(file);
119+
req.url += '/index.html';
120+
} catch {
121+
req.url = '/404/index.html';
122+
}
123+
124+
return next();
125+
});
126+
}
127+
};
128+
}
129+
130+
/**
131+
* @returns {import('vite').Plugin}
132+
*/
133+
function netlifyPlugin() {
134+
const lambdaDir = path.join(__dirname, 'src', 'lambda');
135+
136+
async function netlifyFunctionMiddleware(req, res, next) {
137+
if (!req.url) return next();
138+
139+
const url = new URL(req.url, `http://${req.headers.host}`);
140+
if (!url.pathname.startsWith('/.netlify/functions/')) return next();
141+
142+
const file = path.join(
143+
lambdaDir,
144+
url.pathname
145+
.slice('/.netlify/functions/'.length)
146+
.split(path.posix.sep)
147+
.join(path.sep)
148+
);
149+
150+
const m = await import(`${file}.js`);
151+
const result = await m.handler({
152+
queryStringParameters: Object.fromEntries(url.searchParams)
153+
});
154+
155+
for (const [k, v] of Object.entries(result.headers)) {
156+
res.setHeader(k, v);
157+
}
158+
159+
res.statusCode = result.statusCode;
160+
res.end(result.body);
161+
}
162+
163+
return {
164+
name: 'netlify-plugin',
165+
configureServer(server) {
166+
server.middlewares.use(netlifyFunctionMiddleware);
167+
},
168+
configurePreviewServer(server) {
169+
server.middlewares.use(netlifyFunctionMiddleware);
170+
}
171+
};
172+
}
173+
86174
/**
87175
* @returns {import('vite').Plugin}
88176
*/

0 commit comments

Comments
 (0)