-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: include server assets for Vercel serverless functions #10979
Changes from all commits
cbed243
4915822
fc081d0
e45f4ce
045f343
eeb1cf5
9ec0f82
ac6f3f7
9ce6edb
d8aec4b
ad67ee2
407af73
df45d57
efa240d
816fe44
09a28fb
7390ed8
2c9e86c
957dc06
396d48c
bb1d891
3449ca2
8fbc1aa
306dcde
71a722c
5e09b0b
7625adb
028f35e
9401f07
abafe51
7312bd9
010081f
d8dbb21
d75ad7c
9d0e3a4
9d93465
2355ef6
ea274ec
2784729
82488f6
928d53b
39745e6
cde2295
7699bfd
c4ee169
627cce8
3ac5e78
0e78235
084d97b
c2f8c84
80a6bab
068ded2
557e4e1
8dcb57c
125ac3f
fc09cb7
821c673
c96c33d
3b7127a
463ffb9
cb58b72
6f0fcc0
88b6800
3a0929c
509a698
9f03b6b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@sveltejs/adapter-vercel': minor | ||
--- | ||
|
||
feat: bundle server assets with serverless functions |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@sveltejs/kit': minor | ||
--- | ||
|
||
feat: adapter method to get server assets used by each route |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
.DS_Store | ||
node_modules | ||
.vercel |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,8 +59,8 @@ const plugin = function (defaults = {}) { | |
|
||
/** | ||
* @param {string} name | ||
* @param {import('.').ServerlessConfig} config | ||
* @param {import('@sveltejs/kit').RouteDefinition<import('.').Config>[]} routes | ||
* @param {import('./index.js').ServerlessConfig} config | ||
* @param {import('@sveltejs/kit').RouteDefinition<import('./index.js').Config>[]} routes | ||
*/ | ||
async function generate_serverless_function(name, config, routes) { | ||
const relativePath = path.posix.relative(tmp, builder.getServerDirectory()); | ||
|
@@ -81,14 +81,15 @@ const plugin = function (defaults = {}) { | |
builder, | ||
`${tmp}/index.js`, | ||
`${dirs.functions}/${name}.func`, | ||
config | ||
config, | ||
routes | ||
); | ||
} | ||
|
||
/** | ||
* @param {string} name | ||
* @param {import('.').EdgeConfig} config | ||
* @param {import('@sveltejs/kit').RouteDefinition<import('.').EdgeConfig>[]} routes | ||
* @param {import('./index.js').EdgeConfig} config | ||
* @param {import('@sveltejs/kit').RouteDefinition<import('./index.js').EdgeConfig>[]} routes | ||
*/ | ||
async function generate_edge_function(name, config, routes) { | ||
const tmp = builder.getBuildDirectory(`vercel-tmp/${name}`); | ||
|
@@ -135,7 +136,7 @@ const plugin = function (defaults = {}) { | |
); | ||
} | ||
|
||
/** @type {Map<string, { i: number, config: import('.').Config, routes: import('@sveltejs/kit').RouteDefinition<import('.').Config>[] }>} */ | ||
/** @type {Map<string, { i: number, config: import('./index.js').Config, routes: import('@sveltejs/kit').RouteDefinition<import('./index.js').Config>[] }>} */ | ||
const groups = new Map(); | ||
|
||
/** @type {Map<string, { hash: string, route_id: string }>} */ | ||
|
@@ -144,7 +145,7 @@ const plugin = function (defaults = {}) { | |
/** @type {Map<string, string>} */ | ||
const functions = new Map(); | ||
|
||
/** @type {Map<import('@sveltejs/kit').RouteDefinition<import('.').Config>, { expiration: number | false, bypassToken: string | undefined, allowQuery: string[], group: number, passQuery: true }>} */ | ||
/** @type {Map<import('@sveltejs/kit').RouteDefinition<import('./index.js').Config>, { expiration: number | false, bypassToken: string | undefined, allowQuery: string[], group: number, passQuery: true }>} */ | ||
const isr_config = new Map(); | ||
|
||
/** @type {Set<string>} */ | ||
|
@@ -163,7 +164,7 @@ const plugin = function (defaults = {}) { | |
} | ||
|
||
const node_runtime = /nodejs([0-9]+)\.x/.exec(runtime); | ||
if (runtime !== 'edge' && (!node_runtime || node_runtime[1] < 18)) { | ||
if (runtime !== 'edge' && (!node_runtime || +node_runtime[1] < 18)) { | ||
throw new Error( | ||
`Invalid runtime '${runtime}' for route ${route.id}. Valid runtimes are 'edge' and 'nodejs18.x' or higher ` + | ||
'(see the Node.js Version section in your Vercel project settings for info on the currently supported versions).' | ||
|
@@ -368,7 +369,7 @@ function write(file, data) { | |
// This function is duplicated in adapter-static | ||
/** | ||
* @param {import('@sveltejs/kit').Builder} builder | ||
* @param {import('.').Config} config | ||
* @param {import('index.js').Config} config | ||
*/ | ||
function static_vercel_config(builder, config) { | ||
/** @type {any[]} */ | ||
|
@@ -377,8 +378,11 @@ function static_vercel_config(builder, config) { | |
/** @type {Record<string, { path: string }>} */ | ||
const overrides = {}; | ||
|
||
/** @type {import('./index').ImagesConfig} */ | ||
const images = config.images; | ||
/** @type {import('./index.js').ImagesConfig | undefined} */ | ||
let images; | ||
if (config.runtime !== 'edge') { | ||
images = /** @type {import('./index.js').ServerlessConfig} */ (config).images; | ||
} | ||
Comment on lines
+383
to
+385
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's this change about? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah I was trying to resolve some type issues in the adapter but I didn't fully revert those changes. I'll revert them properly and defer them to another PR |
||
|
||
for (const [src, redirect] of builder.prerendered.redirects) { | ||
prerendered_redirects.push({ | ||
|
@@ -434,9 +438,10 @@ function static_vercel_config(builder, config) { | |
* @param {import('@sveltejs/kit').Builder} builder | ||
* @param {string} entry | ||
* @param {string} dir | ||
* @param {import('.').ServerlessConfig} config | ||
* @param {import('./index.js').ServerlessConfig} config | ||
* @param {import('@sveltejs/kit').RouteDefinition[]} routes | ||
*/ | ||
async function create_function_bundle(builder, entry, dir, config) { | ||
async function create_function_bundle(builder, entry, dir, config, routes) { | ||
fs.rmSync(dir, { force: true, recursive: true }); | ||
|
||
let base = entry; | ||
|
@@ -544,6 +549,24 @@ async function create_function_bundle(builder, entry, dir, config) { | |
) | ||
); | ||
|
||
const server_assets = builder.getServerAssets(); | ||
eltigerchino marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let routes_assets = new Set(server_assets.rootErrorPage); | ||
|
||
for (const route of routes) { | ||
const assets = server_assets.routes.get(route.id); | ||
if (assets) { | ||
routes_assets = new Set([...routes_assets, ...assets]); | ||
} | ||
} | ||
|
||
if (server_assets.hooks) { | ||
routes_assets = new Set([...routes_assets, ...server_assets.hooks]); | ||
} | ||
|
||
for (const asset of routes_assets) { | ||
builder.copy(path.join(builder.getServerDirectory(), asset), path.join(dir, asset)); | ||
} | ||
|
||
write(`${dir}/package.json`, JSON.stringify({ type: 'module' })); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.DS_Store | ||
node_modules | ||
/build | ||
/.svelte-kit | ||
/package | ||
.env | ||
.env.* | ||
!.env.example | ||
vite.config.js.timestamp-* | ||
vite.config.ts.timestamp-* |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
engine-strict=true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "~TODO~", | ||
"version": "0.0.1", | ||
"private": true, | ||
"scripts": { | ||
"dev": "vite dev", | ||
"build": "vite build", | ||
"preview": "vite preview", | ||
"test": "playwright test" | ||
}, | ||
"devDependencies": { | ||
"@sveltejs/kit": "workspace:^", | ||
"svelte": "^4.2.8", | ||
"typescript": "^5.3.3", | ||
"vite": "^5.0.8" | ||
}, | ||
"type": "module" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { config as default } from '../../utils.js'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// See https://kit.svelte.dev/docs/types#app | ||
// for information about these interfaces | ||
declare global { | ||
namespace App { | ||
// interface Error {} | ||
// interface Locals {} | ||
// interface PageData {} | ||
// interface Platform {} | ||
} | ||
} | ||
|
||
export {}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<link rel="icon" href="%sveltekit.assets%/favicon.png" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
%sveltekit.head% | ||
</head> | ||
<body data-sveltekit-preload-data="hover"> | ||
<div style="display: contents">%sveltekit.body%</div> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import text from '$lib/hooks.server.js.txt'; | ||
|
||
export async function handle({ event, resolve }) { | ||
event.setHeaders({ 'x-server-asset': text }); | ||
return resolve(event); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
+error.svelte |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
+layout.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
+layout.server.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
+layout.svelte |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
+page.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
+page.server.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
+page.svelte |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
+server.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
hooks.server.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
root_error |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
root_layout |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import text from './transitive.txt'; | ||
|
||
export { text }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
transitive |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<script> | ||
import asset from '$lib/root_error.txt'; | ||
|
||
/** @type {import('./$types').PageData}*/ | ||
export let data; | ||
</script> | ||
|
||
<h1>{data}</h1> | ||
<p>{asset}</p> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import layout from '$lib/+layout.js.txt'; | ||
|
||
export function load({ data }) { | ||
return { ...data, layout }; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import layout_server from '$lib/+layout.server.js.txt'; | ||
|
||
export function load() { | ||
return { layout_server }; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { text } from '$lib/transitive'; | ||
|
||
export function load() { | ||
return { text }; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import server_asset from '$lib/+server.js.txt'; | ||
|
||
export function GET() { | ||
return new Response(server_asset); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<script> | ||
import asset from '$lib/+error.svelte.txt'; | ||
</script> | ||
|
||
<p>{asset}</p> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import layout from '$lib/+layout.js.txt'; | ||
|
||
export function load() { | ||
return { layout }; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<script> | ||
import asset from '$lib/+layout.svelte.txt'; | ||
</script> | ||
|
||
<p>{asset}</p> | ||
|
||
<slot /> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import page_data from '$lib/+page.js.txt'; | ||
|
||
export async function load({ parent, data }) { | ||
return { ...data, ...(await parent()), page_data }; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import page_server_text from '$lib/+page.server.js.txt'; | ||
|
||
export async function load({ parent }) { | ||
return { ...(await parent()), page_server_text }; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<script> | ||
import asset from '$lib/+page.svelte.txt'; | ||
</script> | ||
|
||
<p>{asset}</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels very hacky. Would love it if we could find a neater solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This, for Netlify is approximately the same as the official documented Vercel solution - if you use next you can yomp the cwd and a magical '/../' path together, but if you don't, you have to use __dirname + string concatenation. Neither work on kit, so I went back to join(process.cwd(), /foo/bar/baz).
and locally of course it's all completely different anyway, since these are built-time post-adapter generated dirs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'll revert this documentation change until there's a better solution for Netlify.