diff --git a/packages/vite/src/node/ssr/ssrModuleLoader.ts b/packages/vite/src/node/ssr/ssrModuleLoader.ts index 4cb226de83944e..2b09bc050603ff 100644 --- a/packages/vite/src/node/ssr/ssrModuleLoader.ts +++ b/packages/vite/src/node/ssr/ssrModuleLoader.ts @@ -10,6 +10,7 @@ import { import { transformRequest } from '../server/transformRequest' import type { InternalResolveOptionsWithOverrideConditions } from '../plugins/resolve' import { tryNodeResolve } from '../plugins/resolve' +import { genSourceMapUrl } from '../server/sourcemap' import { ssrDynamicImportKey, ssrExportAllKey, @@ -25,6 +26,16 @@ interface SSRContext { type SSRModule = Record +// eslint-disable-next-line @typescript-eslint/no-empty-function +const AsyncFunction = async function () {}.constructor as typeof Function +let fnDeclarationLineCount = 0 +{ + const body = '/*code*/' + const source = new AsyncFunction('a', 'b', body).toString() + fnDeclarationLineCount = + source.slice(0, source.indexOf(body)).split('\n').length - 1 +} + const pendingModules = new Map>() const pendingImports = new Map() @@ -181,9 +192,17 @@ async function instantiateModule( } } + let sourceMapSuffix = '' + if (result.map) { + const moduleSourceMap = Object.assign({}, result.map, { + // offset the first three lines of the module (function declaration and 'use strict') + mappings: ';'.repeat(fnDeclarationLineCount + 1) + result.map.mappings, + }) + sourceMapSuffix = + '\n//# sourceMappingURL=' + genSourceMapUrl(moduleSourceMap) + } + try { - // eslint-disable-next-line @typescript-eslint/no-empty-function - const AsyncFunction = async function () {}.constructor as typeof Function const initModule = new AsyncFunction( `global`, ssrModuleExportsKey, @@ -191,7 +210,9 @@ async function instantiateModule( ssrImportKey, ssrDynamicImportKey, ssrExportAllKey, - '"use strict";' + result.code + `\n//# sourceURL=${mod.url}`, + '"use strict";\n' + + result.code + + `\n//# sourceURL=${mod.url}${sourceMapSuffix}`, ) await initModule( context.global,