Skip to content

Commit

Permalink
Move server-side fetch responsibility to adapters instead of build …
Browse files Browse the repository at this point in the history
…step (#1066)

* Move server-side fetch to adapters instead of build step

* set global fetch in svelte-kit start

* remove node-fetch from examples

* lockfile

Co-authored-by: Rich Harris <richard.a.harris@gmail.com>
  • Loading branch information
GrygrFlzr and Rich-Harris authored Apr 17, 2021
1 parent 61d7fa0 commit 6e27880
Show file tree
Hide file tree
Showing 14 changed files with 64 additions and 43 deletions.
8 changes: 8 additions & 0 deletions .changeset/gorgeous-hounds-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@sveltejs/adapter-netlify': patch
'@sveltejs/adapter-node': patch
'@sveltejs/adapter-vercel': patch
'@sveltejs/kit': patch
---

Move server-side fetch to adapters instead of build step
39 changes: 19 additions & 20 deletions examples/hn.svelte.dev/src/routes/[list]/rss.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import fetch from 'node-fetch';

const render = (list, items) => `<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
Expand All @@ -11,30 +9,31 @@ const render = (list, items) => `<?xml version="1.0" encoding="UTF-8" ?>
<title>Svelte HN (${list})</title>
<link>https://hn.svelte.dev/${list}/1</link>
</image>
${items.map(item => `
<item>
<title>${item.title}${item.domain ? ` (${item.domain})` : ''}</title>
<link>https://hn.svelte.dev/item/${item.id}</link>
<description><![CDATA[${
item.url ? `<a href="${item.url}">link</a> / ` : ''
}<a href="https://hn.svelte.dev/item/${item.id}">comments</a>
]]></description>
<pubDate>${new Date(item.time * 1000).toUTCString()}</pubDate>
</item>
`).join('\n')}
${items
.map(
(item) => `
<item>
<title>${item.title}${item.domain ? ` (${item.domain})` : ''}</title>
<link>https://hn.svelte.dev/item/${item.id}</link>
<description><![CDATA[${
item.url ? `<a href="${item.url}">link</a> / ` : ''
}<a href="https://hn.svelte.dev/item/${item.id}">comments</a>
]]></description>
<pubDate>${new Date(item.time * 1000).toUTCString()}</pubDate>
</item>
`
)
.join('\n')}
</channel>
</rss>`;

export function get(req, res) {
const list = (
req.params.list === 'top' ? 'news' :
req.params.list === 'new' ? 'newest' :
req.params.list
);
const list =
req.params.list === 'top' ? 'news' : req.params.list === 'new' ? 'newest' : req.params.list;

fetch(`https://api.hnpwa.com/v0/${list}/1.json`)
.then(r => r.json())
.then(items => {
.then((r) => r.json())
.then((items) => {
const feed = render(list, items);
return {
body: feed,
Expand Down
3 changes: 1 addition & 2 deletions examples/realworld.svelte.dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"svelte": "^3.35.0"
},
"dependencies": {
"cookie": "^0.4.1",
"node-fetch": "^2.6.1"
"cookie": "^0.4.1"
}
}
5 changes: 0 additions & 5 deletions examples/realworld.svelte.dev/src/lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ async function send({ method, path, data, token }) {
opts.headers['Authorization'] = `Token ${token}`;
}

const fetch =
typeof window !== 'undefined'
? window.fetch
: await import('node-fetch').then((mod) => mod.default);

return fetch(`${base}/${path}`, opts)
.then((r) => r.text())
.then((json) => {
Expand Down
8 changes: 1 addition & 7 deletions examples/realworld.svelte.dev/svelte.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ module.exports = {
adapter: node(),

// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',

vite: {
ssr: {
noExternal: ['node-fetch']
}
}
target: '#svelte'
}
};
7 changes: 7 additions & 0 deletions packages/adapter-netlify/files/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

import { URLSearchParams } from 'url';
import { render } from './app.mjs'; // eslint-disable-line import/no-unresolved
import fetch, { Response, Request, Headers } from 'node-fetch';

// provide server-side fetch
globalThis.fetch = fetch;
globalThis.Response = Response;
globalThis.Request = Request;
globalThis.Headers = Headers;

export async function handler(event) {
const {
Expand Down
8 changes: 8 additions & 0 deletions packages/adapter-node/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ import sirv from 'sirv';
import { URL, fileURLToPath } from 'url';
// eslint-disable-next-line import/no-unresolved
import { get_body } from '@sveltejs/kit/http';
import fetch, { Response, Request, Headers } from 'node-fetch';

// provide server-side fetch
globalThis.fetch = fetch;
globalThis.Response = Response;
globalThis.Request = Request;
globalThis.Headers = Headers;

// App is a dynamic file built from the application layer.

const __dirname = dirname(fileURLToPath(import.meta.url));
Expand Down
7 changes: 7 additions & 0 deletions packages/adapter-vercel/src/entry.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { URL } from 'url';
// eslint-disable-next-line import/no-unresolved
import { get_body } from '@sveltejs/kit/http';
import fetch, { Response, Request, Headers } from 'node-fetch';

// provide server-side fetch
globalThis.fetch = fetch;
globalThis.Response = Response;
globalThis.Request = Request;
globalThis.Headers = Headers;

export default async (req, res) => {
const { pathname, searchParams } = new URL(req.url || '', 'http://localhost');
Expand Down
1 change: 1 addition & 0 deletions packages/kit/src/core/adapt/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { readFileSync, writeFileSync } from 'fs';
import { dirname, join, resolve as resolve_path } from 'path';
import { parse, pathToFileURL, resolve } from 'url';
import { mkdirp } from '../filesystem/index.js';
import '../node-fetch-global.js';

/** @param {string} html */
function clean_html(html) {
Expand Down
1 change: 1 addition & 0 deletions packages/kit/src/core/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { get_body } from '../http/index.js';
import { copy_assets } from '../utils.js';
import svelte from '@sveltejs/vite-plugin-svelte';
import { get_server } from '../server/index.js';
import '../node-fetch-global.js';

/** @typedef {{ cwd?: string, port: number, host: string, https: boolean, config: import('types/config').ValidatedConfig }} Options */
/** @typedef {import('types/internal').SSRComponent} SSRComponent */
Expand Down
7 changes: 7 additions & 0 deletions packages/kit/src/core/node-fetch-global.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// @ts-nocheck
import fetch, { Response, Request, Headers } from 'node-fetch';

globalThis.fetch = fetch;
globalThis.Response = Response;
globalThis.Request = Request;
globalThis.Headers = Headers;
1 change: 1 addition & 0 deletions packages/kit/src/core/start/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import sirv from 'sirv';
import { get_body } from '../http/index.js';
import { join, resolve } from 'path';
import { get_server } from '../server/index.js';
import '../node-fetch-global.js';

/** @param {string} dir */
const mutable = (dir) =>
Expand Down
9 changes: 2 additions & 7 deletions packages/kit/src/runtime/server/page/load_node.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import fetch, { Response } from 'node-fetch';
import { parse, resolve } from 'url';
import { normalize } from '../../load.js';
import { ssr } from '../index.js';
Expand Down Expand Up @@ -61,7 +60,6 @@ export async function load_node({
* @param {RequestInfo} resource
* @param {RequestInit} opts
*/
// @ts-ignore mismatch between client fetch and node-fetch
fetch: async (resource, opts = {}) => {
/** @type {string} */
let url;
Expand Down Expand Up @@ -98,10 +96,7 @@ export async function load_node({

if (parsed.protocol) {
// external fetch
response = await fetch(
parsed.href,
/** @type {import('node-fetch').RequestInit} */ (opts)
);
response = await fetch(parsed.href, /** @type {RequestInit} */ (opts));
} else {
// otherwise we're dealing with an internal fetch
const resolved = resolve(request.path, parsed.pathname);
Expand All @@ -127,7 +122,7 @@ export async function load_node({
// TODO we need to know what protocol to use
response = await fetch(
`http://${page.host}/${asset.file}`,
/** @type {import('node-fetch').RequestInit} */ (opts)
/** @type {RequestInit} */ (opts)
);
}
}
Expand Down
3 changes: 1 addition & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6e27880

Please sign in to comment.