diff --git a/.changeset/few-llamas-raise.md b/.changeset/few-llamas-raise.md new file mode 100644 index 000000000000..f7b32c626f75 --- /dev/null +++ b/.changeset/few-llamas-raise.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/adapter-node': patch +--- + +fix: build output stuck on top level await diff --git a/packages/adapter-node/ambient.d.ts b/packages/adapter-node/ambient.d.ts index 6843a8aa5ec7..7d45ea6dc64a 100644 --- a/packages/adapter-node/ambient.d.ts +++ b/packages/adapter-node/ambient.d.ts @@ -1,3 +1,7 @@ +declare module 'ENV' { + export function env(key: string, fallback?: any): string; +} + declare module 'HANDLER' { export const handler: import('polka').Middleware; } @@ -13,11 +17,6 @@ declare module 'SERVER' { export { Server } from '@sveltejs/kit'; } -interface ImportMeta { - SERVER_DIR: string; - ENV_PREFIX?: string; -} - declare namespace App { export interface Platform { /** diff --git a/packages/adapter-node/index.d.ts b/packages/adapter-node/index.d.ts index c3b224198ddb..12ea6273dd66 100644 --- a/packages/adapter-node/index.d.ts +++ b/packages/adapter-node/index.d.ts @@ -1,6 +1,10 @@ import { Adapter } from '@sveltejs/kit'; import './ambient.js'; +declare global { + const ENV_PREFIX: string; +} + interface AdapterOptions { out?: string; precompress?: boolean; diff --git a/packages/adapter-node/index.js b/packages/adapter-node/index.js index 69eaee9e3e91..8d5c1629a4cf 100644 --- a/packages/adapter-node/index.js +++ b/packages/adapter-node/index.js @@ -1,15 +1,11 @@ -import commonjs from '@rollup/plugin-commonjs'; -import json from '@rollup/plugin-json'; -import { nodeResolve } from '@rollup/plugin-node-resolve'; -import { createFilter, normalizePath } from '@rollup/pluginutils'; -import { existsSync, readFileSync, writeFileSync } from 'node:fs'; -import { readFile } from 'node:fs/promises'; -import path from 'node:path'; +import { readFileSync, writeFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { rollup } from 'rollup'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; -/** @param {string} path */ -const resolve = (path) => fileURLToPath(new URL(path, import.meta.url)); +const files = fileURLToPath(new URL('./files', import.meta.url).href); /** @type {import('.').default} */ export default function (opts = {}) { @@ -19,8 +15,7 @@ export default function (opts = {}) { name: '@sveltejs/adapter-node', async adapt(builder) { - // use an adjacent temporary directory so that any relative paths in eg. sourcemaps don't break - const tmp = path.join(path.dirname(builder.getServerDirectory()), 'adapter-node'); + const tmp = builder.getBuildDirectory('adapter-node'); builder.rimraf(out); builder.rimraf(tmp); @@ -55,85 +50,45 @@ export default function (opts = {}) { // will get included in the bundled code const bundle = await rollup({ input: { - handler: resolve('./src/handler.js'), - index: resolve('./src/index.js') + index: `${tmp}/index.js`, + manifest: `${tmp}/manifest.js` }, external: [ // dependencies could have deep exports, so we need a regex ...Object.keys(pkg.dependencies || {}).map((d) => new RegExp(`^${d}(\\/.*)?$`)) ], plugins: [ - { - name: 'adapter-node-resolve', - resolveId(id) { - switch (id) { - case 'MANIFEST': - return `${tmp}/manifest.js`; - case 'SERVER': - return `${tmp}/index.js`; - case 'SHIMS': - return '\0virtual:SHIMS'; - } - }, - load(id) { - if (id === '\0virtual:SHIMS') { - return polyfill - ? "import { installPolyfills } from '@sveltejs/kit/node/polyfills'; installPolyfills();" - : ''; - } - }, - resolveImportMeta(property, { chunkId, moduleId }) { - if (property === 'SERVER_DIR' && moduleId === resolve('./src/handler.js')) { - const segments = chunkId.split('/').length - 1; - - return `new URL("${'../'.repeat(segments) || '.'}", import.meta.url)`; - } else if (property === 'ENV_PREFIX' && moduleId === resolve('./src/env.js')) { - return JSON.stringify(envPrefix); - } - } - }, nodeResolve({ preferBuiltins: true, exportConditions: ['node'] }), commonjs({ strictRequires: true }), - json(), - merge_sourcemap_plugin(tmp) + json() ] }); await bundle.write({ - dir: out, + dir: `${out}/server`, format: 'esm', sourcemap: true, - chunkFileNames: 'server/chunks/[name]-[hash].js', - // without this rollup will insert some imports to try speed up - // module loading but it doesn't really affect anything on the server side - hoistTransitiveImports: false + chunkFileNames: 'chunks/[name]-[hash].js' }); - } - }; -} -/** - * Load sourcemaps for files in the tmp directory so that the final ones - * point to the original source files, instead of the generated files in outDir. - * @param {string} tmp - * @returns {import('rollup').Plugin} - */ -function merge_sourcemap_plugin(tmp) { - const should_process_sourcemaps = createFilter(`${normalizePath(tmp)}/**/*.js`); + builder.copy(files, out, { + replace: { + ENV: './env.js', + HANDLER: './handler.js', + MANIFEST: './server/manifest.js', + SERVER: './server/index.js', + SHIMS: './shims.js', + ENV_PREFIX: JSON.stringify(envPrefix) + } + }); - return { - name: 'adapter-node-sourcemap-loader', - async load(id) { - if (!should_process_sourcemaps(id)) return; - if (!existsSync(`${id}.map`)) return; - const [code, map] = await Promise.all([ - readFile(id, 'utf-8'), - readFile(`${id}.map`, 'utf-8') - ]); - return { code, map }; + // If polyfills aren't wanted then clear the file + if (!polyfill) { + writeFileSync(`${out}/shims.js`, '', 'utf-8'); + } } }; } diff --git a/packages/adapter-node/package.json b/packages/adapter-node/package.json index fe9f87f248a0..7919ffd91960 100644 --- a/packages/adapter-node/package.json +++ b/packages/adapter-node/package.json @@ -19,32 +19,35 @@ }, "types": "index.d.ts", "files": [ - "src", + "files", "index.js", "index.d.ts" ], "scripts": { + "dev": "rimraf files && rollup -cw", + "build": "rimraf files && rollup -c", "test": "echo \"tests temporarily disabled\" # c8 vitest run", "check": "tsc", "lint": "prettier --check . --config ../../.prettierrc --ignore-path .gitignore", - "format": "pnpm lint --write" + "format": "pnpm lint --write", + "prepublishOnly": "pnpm build" }, "devDependencies": { + "@polka/url": "^1.0.0-next.21", "@sveltejs/kit": "workspace:^", "@types/node": "^16.18.6", "c8": "^8.0.0", + "polka": "^1.0.0-next.22", + "rimraf": "^5.0.0", + "sirv": "^2.0.3", "typescript": "^4.9.4", "vitest": "^0.32.2" }, "dependencies": { - "@polka/url": "^1.0.0-next.21", "@rollup/plugin-commonjs": "^25.0.0", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.1", - "@rollup/pluginutils": "^5.0.2", - "polka": "^1.0.0-next.22", - "rollup": "^3.7.0", - "sirv": "^2.0.2" + "rollup": "^3.7.0" }, "peerDependencies": { "@sveltejs/kit": "^1.0.0" diff --git a/packages/adapter-node/rollup.config.js b/packages/adapter-node/rollup.config.js new file mode 100644 index 000000000000..16c4a20c37a7 --- /dev/null +++ b/packages/adapter-node/rollup.config.js @@ -0,0 +1,44 @@ +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import { builtinModules } from 'node:module'; + +export default [ + { + input: 'src/index.js', + output: { + file: 'files/index.js', + format: 'esm' + }, + plugins: [nodeResolve({ preferBuiltins: true }), commonjs(), json()], + external: ['ENV', 'HANDLER', ...builtinModules] + }, + { + input: 'src/env.js', + output: { + file: 'files/env.js', + format: 'esm' + }, + plugins: [nodeResolve(), commonjs(), json()], + external: ['HANDLER', ...builtinModules] + }, + { + input: 'src/handler.js', + output: { + file: 'files/handler.js', + format: 'esm', + inlineDynamicImports: true + }, + plugins: [nodeResolve(), commonjs(), json()], + external: ['ENV', 'MANIFEST', 'SERVER', 'SHIMS', ...builtinModules] + }, + { + input: 'src/shims.js', + output: { + file: 'files/shims.js', + format: 'esm' + }, + plugins: [nodeResolve(), commonjs()], + external: builtinModules + } +]; diff --git a/packages/adapter-node/src/env.js b/packages/adapter-node/src/env.js index 75a7dcc93b28..841bddf2c237 100644 --- a/packages/adapter-node/src/env.js +++ b/packages/adapter-node/src/env.js @@ -1,4 +1,4 @@ -export const ENV_PREFIX = import.meta.ENV_PREFIX; +/* global ENV_PREFIX */ const expected = new Set([ 'SOCKET_PATH', diff --git a/packages/adapter-node/src/handler.js b/packages/adapter-node/src/handler.js index 495f35db5236..bae1854bdd7e 100644 --- a/packages/adapter-node/src/handler.js +++ b/packages/adapter-node/src/handler.js @@ -1,16 +1,15 @@ import 'SHIMS'; - import fs from 'node:fs'; import path from 'node:path'; +import sirv from 'sirv'; import { fileURLToPath } from 'node:url'; - import { parse as polka_url_parser } from '@polka/url'; import { getRequest, setResponse } from '@sveltejs/kit/node'; -import sirv from 'sirv'; - -import { env, ENV_PREFIX } from './env.js'; -import { manifest, prerendered } from 'MANIFEST'; import { Server } from 'SERVER'; +import { manifest, prerendered } from 'MANIFEST'; +import { env } from 'ENV'; + +/* global ENV_PREFIX */ const server = new Server(manifest); await server.init({ env: process.env }); @@ -21,7 +20,7 @@ const protocol_header = env('PROTOCOL_HEADER', '').toLowerCase(); const host_header = env('HOST_HEADER', 'host').toLowerCase(); const body_size_limit = parseInt(env('BODY_SIZE_LIMIT', '524288')); -const dir = fileURLToPath(import.meta.SERVER_DIR); +const dir = path.dirname(fileURLToPath(import.meta.url)); /** * @param {string} path diff --git a/packages/adapter-node/src/index.js b/packages/adapter-node/src/index.js index 5832b244a51e..ea3feee05860 100644 --- a/packages/adapter-node/src/index.js +++ b/packages/adapter-node/src/index.js @@ -1,5 +1,5 @@ -import { handler } from './handler.js'; -import { env } from './env.js'; +import { handler } from 'HANDLER'; +import { env } from 'ENV'; import polka from 'polka'; export const path = env('SOCKET_PATH', false); diff --git a/packages/adapter-node/src/shims.js b/packages/adapter-node/src/shims.js new file mode 100644 index 000000000000..2490311daa1e --- /dev/null +++ b/packages/adapter-node/src/shims.js @@ -0,0 +1,2 @@ +import { installPolyfills } from '@sveltejs/kit/node/polyfills'; +installPolyfills(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b114054150c6..1371ee8bf67e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -171,9 +171,6 @@ importers: packages/adapter-node: dependencies: - '@polka/url': - specifier: ^1.0.0-next.21 - version: 1.0.0-next.21 '@rollup/plugin-commonjs': specifier: ^25.0.0 version: 25.0.0(rollup@3.7.0) @@ -183,19 +180,13 @@ importers: '@rollup/plugin-node-resolve': specifier: ^15.0.1 version: 15.0.1(rollup@3.7.0) - '@rollup/pluginutils': - specifier: ^5.0.2 - version: 5.0.2(rollup@3.7.0) - polka: - specifier: ^1.0.0-next.22 - version: 1.0.0-next.22 rollup: specifier: ^3.7.0 version: 3.7.0 - sirv: - specifier: ^2.0.2 - version: 2.0.3 devDependencies: + '@polka/url': + specifier: ^1.0.0-next.21 + version: 1.0.0-next.21 '@sveltejs/kit': specifier: workspace:^ version: link:../kit @@ -205,6 +196,15 @@ importers: c8: specifier: ^8.0.0 version: 8.0.0 + polka: + specifier: ^1.0.0-next.22 + version: 1.0.0-next.22 + rimraf: + specifier: ^5.0.0 + version: 5.0.0 + sirv: + specifier: ^2.0.3 + version: 2.0.3 typescript: specifier: ^4.9.4 version: 4.9.4 @@ -4808,7 +4808,7 @@ packages: dependencies: '@polka/url': 1.0.0-next.21 trouter: 3.2.0 - dev: false + dev: true /postcss-load-config@3.1.4(postcss@8.4.23): resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} @@ -5084,7 +5084,7 @@ packages: /regexparam@1.3.0: resolution: {integrity: sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==} engines: {node: '>=6'} - dev: false + dev: true /regexparam@2.0.1: resolution: {integrity: sha512-zRgSaYemnNYxUv+/5SeoHI0eJIgTL/A2pUtXUPLHQxUldagouJ9p+K6IbIZ/JiQuCEv2E2B1O11SjVQy3aMCkw==} @@ -5408,6 +5408,7 @@ packages: '@polka/url': 1.0.0-next.21 mrmime: 1.0.1 totalist: 3.0.0 + dev: true /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -5966,7 +5967,7 @@ packages: engines: {node: '>=6'} dependencies: regexparam: 1.3.0 - dev: false + dev: true /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}