1- import { readFileSync , writeFileSync } from 'node:fs' ;
2- import { fileURLToPath } from 'node:url' ;
3- import { rollup } from 'rollup' ;
4- import { nodeResolve } from '@rollup/plugin-node-resolve' ;
51import commonjs from '@rollup/plugin-commonjs' ;
62import json from '@rollup/plugin-json' ;
3+ import { nodeResolve } from '@rollup/plugin-node-resolve' ;
4+ import { createFilter , normalizePath } from '@rollup/pluginutils' ;
5+ import { existsSync , readFileSync , writeFileSync } from 'node:fs' ;
6+ import { readFile } from 'node:fs/promises' ;
7+ import path from 'node:path' ;
8+ import { fileURLToPath } from 'node:url' ;
9+ import { rollup } from 'rollup' ;
710
8- const files = fileURLToPath ( new URL ( './files' , import . meta. url ) . href ) ;
11+ /** @param {string } path */
12+ const resolve = ( path ) => fileURLToPath ( new URL ( path , import . meta. url ) ) ;
913
1014/** @type {import('.').default } */
1115export default function ( opts = { } ) {
@@ -15,7 +19,8 @@ export default function (opts = {}) {
1519 name : '@sveltejs/adapter-node' ,
1620
1721 async adapt ( builder ) {
18- const tmp = builder . getBuildDirectory ( 'adapter-node' ) ;
22+ // use an adjacent temporary directory so that any relative paths in eg. sourcemaps don't break
23+ const tmp = path . join ( path . dirname ( builder . getServerDirectory ( ) ) , 'adapter-node' ) ;
1924
2025 builder . rimraf ( out ) ;
2126 builder . rimraf ( tmp ) ;
@@ -50,45 +55,85 @@ export default function (opts = {}) {
5055 // will get included in the bundled code
5156 const bundle = await rollup ( {
5257 input : {
53- index : ` ${ tmp } /index .js` ,
54- manifest : ` ${ tmp } /manifest .js`
58+ handler : resolve ( './src/handler .js' ) ,
59+ index : resolve ( './src/index .js' )
5560 } ,
5661 external : [
5762 // dependencies could have deep exports, so we need a regex
5863 ...Object . keys ( pkg . dependencies || { } ) . map ( ( d ) => new RegExp ( `^${ d } (\\/.*)?$` ) )
5964 ] ,
6065 plugins : [
66+ {
67+ name : 'adapter-node-resolve' ,
68+ resolveId ( id ) {
69+ switch ( id ) {
70+ case 'MANIFEST' :
71+ return `${ tmp } /manifest.js` ;
72+ case 'SERVER' :
73+ return `${ tmp } /index.js` ;
74+ case 'SHIMS' :
75+ return '\0virtual:SHIMS' ;
76+ }
77+ } ,
78+ load ( id ) {
79+ if ( id === '\0virtual:SHIMS' ) {
80+ return polyfill
81+ ? "import { installPolyfills } from '@sveltejs/kit/node/polyfills'; installPolyfills();"
82+ : '' ;
83+ }
84+ } ,
85+ resolveImportMeta ( property , { chunkId, moduleId } ) {
86+ if ( property === 'SERVER_DIR' && moduleId === resolve ( './src/handler.js' ) ) {
87+ const segments = chunkId . split ( '/' ) . length - 1 ;
88+
89+ return `new URL("${ '../' . repeat ( segments ) || '.' } ", import.meta.url)` ;
90+ } else if ( property === 'ENV_PREFIX' && moduleId === resolve ( './src/env.js' ) ) {
91+ return JSON . stringify ( envPrefix ) ;
92+ }
93+ }
94+ } ,
6195 nodeResolve ( {
6296 preferBuiltins : true ,
6397 exportConditions : [ 'node' ]
6498 } ) ,
6599 commonjs ( { strictRequires : true } ) ,
66- json ( )
100+ json ( ) ,
101+ merge_sourcemap_plugin ( tmp )
67102 ]
68103 } ) ;
69104
70105 await bundle . write ( {
71- dir : ` ${ out } /server` ,
106+ dir : out ,
72107 format : 'esm' ,
73108 sourcemap : true ,
74- chunkFileNames : 'chunks/[name]-[hash].js'
109+ chunkFileNames : 'server/chunks/[name]-[hash].js' ,
110+ // without this rollup will insert some imports to try speed up
111+ // module loading but it doesn't really affect anything on the server side
112+ hoistTransitiveImports : false
75113 } ) ;
114+ }
115+ } ;
116+ }
76117
77- builder . copy ( files , out , {
78- replace : {
79- ENV : './env.js' ,
80- HANDLER : './handler.js' ,
81- MANIFEST : './server/manifest.js' ,
82- SERVER : './server/index.js' ,
83- SHIMS : './shims.js' ,
84- ENV_PREFIX : JSON . stringify ( envPrefix )
85- }
86- } ) ;
118+ /**
119+ * Load sourcemaps for files in the tmp directory so that the final ones
120+ * point to the original source files, instead of the generated files in outDir.
121+ * @param {string } tmp
122+ * @returns {import('rollup').Plugin }
123+ */
124+ function merge_sourcemap_plugin ( tmp ) {
125+ const should_process_sourcemaps = createFilter ( `${ normalizePath ( tmp ) } /**/*.js` ) ;
87126
88- // If polyfills aren't wanted then clear the file
89- if ( ! polyfill ) {
90- writeFileSync ( `${ out } /shims.js` , '' , 'utf-8' ) ;
91- }
127+ return {
128+ name : 'adapter-node-sourcemap-loader' ,
129+ async load ( id ) {
130+ if ( ! should_process_sourcemaps ( id ) ) return ;
131+ if ( ! existsSync ( `${ id } .map` ) ) return ;
132+ const [ code , map ] = await Promise . all ( [
133+ readFile ( id , 'utf-8' ) ,
134+ readFile ( `${ id } .map` , 'utf-8' )
135+ ] ) ;
136+ return { code, map } ;
92137 }
93138 } ;
94139}
0 commit comments