Skip to content

Commit

Permalink
feat: add suport for sourcemaps as URL (if CACHE enabled)
Browse files Browse the repository at this point in the history
  • Loading branch information
esroyo committed Jun 27, 2024
1 parent c505c40 commit 4f2e2dd
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
6 changes: 5 additions & 1 deletion deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ export { rollup, VERSION as rollupVersion } from 'npm:[email protected]';
export { loadSync as dotenvLoad } from 'jsr:@std/[email protected]';
export { serve } from 'jsr:@std/[email protected]';
export { dirname, resolve } from 'jsr:@std/[email protected]';
export { dirname as urlDirname, join as urlJoin } from 'jsr:@std/[email protected]';
export {
basename as urlBasename,
dirname as urlDirname,
join as urlJoin,
} from 'jsr:@std/[email protected]';
export { default as request } from 'npm:[email protected]';
export { get as kvGet, set as kvSet } from 'jsr:@kitsonk/[email protected]/blob';
export { getBuildTargetFromUA } from 'npm:[email protected]';
Expand Down
46 changes: 44 additions & 2 deletions src/create-request-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
nodeRequest,
} from './utils.ts';
import { toSystemjs } from './to-systemjs.ts';
import { getBuildTargetFromUA, opentelemetry } from '../deps.ts';
import { getBuildTargetFromUA, opentelemetry, urlBasename } from '../deps.ts';
import type { Cache, Config, OpenTelemetry, ResponseProps } from './types.ts';

export function createRequestHandler(
Expand Down Expand Up @@ -186,13 +186,23 @@ export function createRequestHandler(
)
.toString();
const isRawRequest = selfUrl.searchParams.has('raw');
const isMapRequest = publicSelfUrl.endsWith('.map');
rootSpan?.setAttributes({
'esm.build.target': buildTarget,
'http.route': BASE_PATH,
'http.url': publicSelfUrl,
});
if (isMapRequest && !CACHE) {
// Sourcemaps are only enabled with CACHE
// otherwise they are served as inlined data uris
// thus it is not possible to receive a sourcemap request when !CACHE
return new Response(null, { status: 404 });
}
if (CACHE) {
const cacheKey = [publicSelfUrl, buildTarget];
const cacheKey = [
isMapRequest ? publicSelfUrl.slice(0, -4) : publicSelfUrl,
buildTarget,
];
const cacheReadSpan = tracer.startSpan('cache-read', {
attributes: {
'span.type': 'cache',
Expand All @@ -202,6 +212,23 @@ export function createRequestHandler(
const cachedValue = await cache?.get(cacheKey);
cacheReadSpan.addEvent(cachedValue ? 'cache-hit' : 'cache-miss');
cacheReadSpan.end();
if (isMapRequest) {
// A sourcemap request always should come after the original JS module
// thus, it MUST be already in the cache of the original JS module URL
// or we just return an 404
if (cachedValue && cachedValue.map) {
return new Response(cachedValue.map, {
headers: {
'access-control-allow-methods': '*',
'access-control-allow-origin': '*',
'cache-control':
'public, max-age=31536000, immutable',
'content-type': 'application/json; charset=utf-8',
},
});
}
return new Response(null, { status: 404 });
}
if (cachedValue) {
const response = await createFinalResponse(
{
Expand Down Expand Up @@ -233,19 +260,33 @@ export function createRequestHandler(
redirect: 'manual',
});
let body = await upstreamResponse.text();
let map: string | undefined = undefined;
upstreamSpan.end();
if (!isRawRequest && isJsResponse(upstreamResponse)) {
const sourcemapSpan = tracer.startSpan('sourcemap');
const sourceModule = await buildSourceModule(
body,
upstreamUrlString,
);
const canGenerateSourcemap =
!!(typeof sourceModule === 'object' && sourceModule.map);
const sourcemap = canGenerateSourcemap
? (CACHE ? true : 'inline')
: false;
const sourcemapFileNames = sourcemap === true
? `${urlBasename(publicSelfUrl)}.map`
: undefined;
sourcemapSpan.end();
const buildSpan = tracer.startSpan('build');
const buildResult = await toSystemjs(sourceModule, {
banner: OUTPUT_BANNER,
sourcemap,
sourcemapFileNames,
}, config);
body = replaceOrigin(buildResult.code);
if (sourcemap === true) {
map = buildResult.map;
}
buildSpan.end();
} else {
body = replaceOrigin(body);
Expand All @@ -259,6 +300,7 @@ export function createRequestHandler(
denyHeaders,
replaceOriginHeaders,
),
map,
status: upstreamResponse.status,
statusText: upstreamResponse.statusText,
},
Expand Down
1 change: 0 additions & 1 deletion src/to-systemjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ export const toSystemjsMain = async (
const outputOptions: OutputOptions = {
dir: 'out', // not really used
format: 'systemjs' as ModuleFormat,
sourcemap: mod.map ? 'inline' : false,
...rollupOutputOptions,
footer: `/* rollup@${rollupVersion}${
rollupOutputOptions.footer ? ` - ${rollupOutputOptions.footer}` : ''
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface HttpZResponseModel {
export type ResponseProps = {
url: string;
body: string;
map?: string;
headers: Headers;
status: number;
statusText: string;
Expand Down

0 comments on commit 4f2e2dd

Please sign in to comment.