Skip to content
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

breaking: require Node 18.13 or newer #11172

Merged
merged 8 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rotten-penguins-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-node': major
---

breaking: remove polyfill option. fetch APIs will now always come from the platform being used. File and crypto APIs will be polyfilled if not available
5 changes: 5 additions & 0 deletions .changeset/thick-suits-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': major
---

breaking: require Node 18.13 or newer
19 changes: 8 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- uses: pnpm/action-setup@v2.4.0
- uses: actions/setup-node@v4
with:
node-version: '16.x'
node-version: '18.x'
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run lint
Expand All @@ -39,9 +39,6 @@ jobs:
fail-fast: false
matrix:
include:
- node-version: 16
os: ubuntu-latest
e2e-browser: 'chromium'
- node-version: 18
os: ubuntu-latest
e2e-browser: 'chromium'
Expand Down Expand Up @@ -79,27 +76,27 @@ jobs:
fail-fast: false
matrix:
include:
- node-version: 16
- node-version: 18
os: windows-2019 # slowness reported on newer versions https://github.com/actions/runner-images/issues/5166
e2e-browser: 'chromium'
mode: 'dev'
- node-version: 16
- node-version: 18
os: ubuntu-latest
e2e-browser: 'firefox'
mode: 'dev'
- node-version: 16
- node-version: 18
os: macOS-latest
e2e-browser: 'webkit'
mode: 'dev'
- node-version: 16
- node-version: 18
os: windows-2019 # slowness reported on newer versions https://github.com/actions/runner-images/issues/5166
e2e-browser: 'chromium'
mode: 'build'
- node-version: 16
- node-version: 18
os: ubuntu-latest
e2e-browser: 'firefox'
mode: 'build'
- node-version: 16
- node-version: 18
os: macOS-latest
e2e-browser: 'webkit'
mode: 'build'
Expand Down Expand Up @@ -134,7 +131,7 @@ jobs:
- uses: pnpm/action-setup@v2.4.0
- uses: actions/setup-node@v4
with:
node-version: 16
node-version: 18
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: cd packages/kit && pnpm prepublishOnly
Expand Down
9 changes: 1 addition & 8 deletions documentation/docs/25-build-and-deploy/40-adapter-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,7 @@ export default {
// default options are shown
out: 'build',
precompress: false,
envPrefix: '',
polyfill: true
envPrefix: ''
})
}
};
Expand Down Expand Up @@ -161,12 +160,6 @@ MY_CUSTOM_ORIGIN=https://my.site \
node build
```

### polyfill

Controls whether your build will load polyfills for missing modules. It defaults to `true`, and should only be disabled when using Node 18.11 or greater.

Note: to use Node's built-in `crypto` global with Node 18 you will need to use the `--experimental-global-webcrypto` flag. This flag is not required with Node 20.

## Custom server

The adapter creates two files in your build directory — `index.js` and `handler.js`. Running `index.js` — e.g. `node build`, if you use the default build directory — will start a server on the configured port.
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-auto/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"devDependencies": {
"@sveltejs/kit": "workspace:^",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"typescript": "^5.3.2"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-cloudflare-workers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"devDependencies": {
"@cloudflare/kv-asset-handler": "^0.3.0",
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"typescript": "^5.3.2"
},
"peerDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"worktop": "0.8.0-next.15"
},
"devDependencies": {
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"@types/ws": "^8.5.3",
"typescript": "^5.3.2"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-netlify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"@rollup/plugin-node-resolve": "^15.2.3",
"@sveltejs/kit": "workspace:^",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"@types/set-cookie-parser": "^2.4.2",
"rollup": "^4.2.0",
"typescript": "^5.3.2",
Expand Down
1 change: 0 additions & 1 deletion packages/adapter-node/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ interface AdapterOptions {
out?: string;
precompress?: boolean;
envPrefix?: string;
polyfill?: boolean;
}

export default function plugin(options?: AdapterOptions): Adapter;
7 changes: 1 addition & 6 deletions packages/adapter-node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const files = fileURLToPath(new URL('./files', import.meta.url).href);

/** @type {import('./index.js').default} */
export default function (opts = {}) {
const { out = 'build', precompress, envPrefix = '', polyfill = true } = opts;
const { out = 'build', precompress, envPrefix = '' } = opts;

return {
name: '@sveltejs/adapter-node',
Expand Down Expand Up @@ -86,11 +86,6 @@ export default function (opts = {}) {
ENV_PREFIX: JSON.stringify(envPrefix)
}
});

// If polyfills aren't wanted then clear the file
if (!polyfill) {
writeFileSync(`${out}/shims.js`, '', 'utf-8');
}
}
};
}
2 changes: 1 addition & 1 deletion packages/adapter-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@polka/url": "^1.0.0-next.23",
"@sveltejs/kit": "workspace:^",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"c8": "^8.0.0",
"polka": "^1.0.0-next.23",
"sirv": "^2.0.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-static/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@playwright/test": "1.30.0",
"@sveltejs/kit": "workspace:^",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"sirv": "^2.0.3",
"svelte": "^4.2.7",
"typescript": "^5.3.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-vercel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"devDependencies": {
"@sveltejs/kit": "workspace:^",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"typescript": "^5.3.2",
"vitest": "^0.34.5"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/enhanced-img/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"devDependencies": {
"@types/estree": "^1.0.2",
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"estree-walker": "^3.0.3",
"rollup": "^4.2.0",
"svelte": "^4.2.7",
Expand Down
7 changes: 3 additions & 4 deletions packages/kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@
"sade": "^1.8.1",
"set-cookie-parser": "^2.6.0",
"sirv": "^2.0.2",
"tiny-glob": "^0.2.9",
"undici": "~5.26.2"
"tiny-glob": "^0.2.9"
},
"devDependencies": {
"@playwright/test": "1.30.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/connect": "^3.4.35",
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"@types/sade": "^1.7.4",
"@types/set-cookie-parser": "^2.4.2",
"dts-buddy": "^0.4.1",
Expand Down Expand Up @@ -96,6 +95,6 @@
},
"types": "types/index.d.ts",
"engines": {
"node": "^16.14 || >=18"
"node": ">=18.13"
}
}
5 changes: 1 addition & 4 deletions packages/kit/src/core/postbuild/analyse.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
} from '../../utils/exports.js';
import { load_config } from '../config/index.js';
import { forked } from '../../utils/fork.js';
import { should_polyfill } from '../../utils/platform.js';
import { installPolyfills } from '../../exports/node/polyfills.js';
import { resolvePath } from '../../exports/index.js';
import { ENDPOINT_METHODS } from '../../constants.js';
Expand All @@ -36,9 +35,7 @@ async function analyse({ manifest_path, env }) {
/** @type {import('types').ServerInternalModule} */
const internal = await import(pathToFileURL(`${server_root}/server/internal.js`).href);

if (should_polyfill) {
installPolyfills();
}
installPolyfills();

// configure `import { building } from '$app/environment'` —
// essential we do this before analysing the code
Expand Down
5 changes: 1 addition & 4 deletions packages/kit/src/core/postbuild/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { dirname, join } from 'node:path';
import { pathToFileURL } from 'node:url';
import { installPolyfills } from '../../exports/node/polyfills.js';
import { mkdirp, posixify, walk } from '../../utils/filesystem.js';
import { should_polyfill } from '../../utils/platform.js';
import { decode_uri, is_root_relative, resolve } from '../../utils/url.js';
import { escape_html_attr } from '../../utils/escape.js';
import { logger } from '../utils.js';
Expand Down Expand Up @@ -94,9 +93,7 @@ async function prerender({ out, manifest_path, metadata, verbose, env }) {
/** @type {import('types').Logger} */
const log = logger({ verbose });

if (should_polyfill) {
installPolyfills();
}
installPolyfills();

/** @type {Map<string, string>} */
const saved = new Map();
Expand Down
39 changes: 5 additions & 34 deletions packages/kit/src/exports/node/polyfills.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,25 @@
import { ReadableStream, TransformStream, WritableStream } from 'node:stream/web';
import buffer from 'node:buffer';
import { webcrypto as crypto } from 'node:crypto';
import { fetch, Response, Request, Headers, FormData, File as UndiciFile } from 'undici';

// `buffer.File` was added in Node 18.13.0 while the `File` global was added in Node 20.0.0
const File = /** @type {import('node:buffer') & { File?: File}} */ (buffer).File ?? UndiciFile;
const File = /** @type {import('node:buffer') & { File?: File}} */ (buffer).File;

/** @type {Record<string, any>} */
const globals_post_node_18_11 = {
const globals = {
crypto,
File
};

/** @type {Record<string, any>} */
// TODO: remove this once we only support Node 18.11+ (the version multipart/form-data was added)
const globals_pre_node_18_11 = {
crypto,
fetch,
Response,
Request,
Headers,
ReadableStream,
TransformStream,
WritableStream,
FormData,
File
};

// exported for dev/preview and node environments
/**
* Make various web APIs available as globals:
* - `crypto`
* - `fetch` (only in node < 18.11)
* - `Headers` (only in node < 18.11)
* - `Request` (only in node < 18.11)
* - `Response` (only in node < 18.11)
* - `File`
*/
export function installPolyfills() {
// Be defensive (we don't know in which environments this is called) and always apply if something goes wrong
let globals = globals_pre_node_18_11;
try {
const version = process.versions.node.split('.').map((n) => parseInt(n, 10));
if ((version[0] === 18 && version[1] >= 11) || version[0] > 18) {
globals = globals_post_node_18_11;
}
} catch (e) {
// ignore
}

for (const name in globals) {
if (name in globalThis) continue;

Object.defineProperty(globalThis, name, {
enumerable: true,
configurable: true,
Expand Down
5 changes: 1 addition & 4 deletions packages/kit/src/exports/vite/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { getRequest, setResponse } from '../../../exports/node/index.js';
import { installPolyfills } from '../../../exports/node/polyfills.js';
import { coalesce_to_error } from '../../../utils/error.js';
import { posixify, resolve_entry, to_fs } from '../../../utils/filesystem.js';
import { should_polyfill } from '../../../utils/platform.js';
import { load_error_page } from '../../../core/config/index.js';
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
import * as sync from '../../../core/sync/sync.js';
Expand All @@ -26,9 +25,7 @@ const cwd = process.cwd();
* @return {Promise<Promise<() => void>>}
*/
export async function dev(vite, vite_config, svelte_config) {
if (should_polyfill) {
installPolyfills();
}
installPolyfills();

const fetch = globalThis.fetch;
globalThis.fetch = (info, init) => {
Expand Down
5 changes: 1 addition & 4 deletions packages/kit/src/exports/vite/preview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { loadEnv, normalizePath } from 'vite';
import { getRequest, setResponse } from '../../../exports/node/index.js';
import { installPolyfills } from '../../../exports/node/polyfills.js';
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
import { should_polyfill } from '../../../utils/platform.js';

/** @typedef {import('http').IncomingMessage} Req */
/** @typedef {import('http').ServerResponse} Res */
Expand All @@ -19,9 +18,7 @@ import { should_polyfill } from '../../../utils/platform.js';
* @param {import('types').ValidatedConfig} svelte_config
*/
export async function preview(vite, vite_config, svelte_config) {
if (should_polyfill) {
installPolyfills();
}
installPolyfills();

const { paths } = svelte_config.kit;
const assets = paths.assets ? SVELTE_KIT_ASSETS : paths.base;
Expand Down
7 changes: 5 additions & 2 deletions packages/kit/src/runtime/server/page/csp.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import { webcrypto } from 'node:crypto';
import { assert, beforeAll, test } from 'vitest';
import { Csp } from './csp.js';

// @ts-expect-error
globalThis.crypto = webcrypto;
// TODO: remove after bumping peer dependency to require Node 20
if (!globalThis.crypto) {
// @ts-expect-error
globalThis.crypto = webcrypto;
}

beforeAll(() => {
// @ts-expect-error
Expand Down
1 change: 0 additions & 1 deletion packages/kit/src/utils/platform.js

This file was deleted.

1 change: 0 additions & 1 deletion packages/kit/test/apps/basics/test/server.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { expect } from '@playwright/test';
import { test } from '../../../utils.js';
import { fetch } from 'undici';
import { createHash, randomBytes } from 'node:crypto';

/** @typedef {import('@playwright/test').Response} Response */
Expand Down
2 changes: 1 addition & 1 deletion packages/migrate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"typescript": "^5.3.2"
},
"devDependencies": {
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"@types/prompts": "^2.4.1",
"@types/semver": "^7.5.0",
"prettier": "^3.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"svelte2tsx": "~0.6.19"
},
"devDependencies": {
"@types/node": "^16.18.6",
"@types/node": "^18.19.1",
"@types/semver": "^7.5.0",
"svelte": "^4.2.7",
"svelte-preprocess": "^5.1.1",
Expand Down