Skip to content

Commit 242d361

Browse files
committed
Fix sourcemap chaining
This commit fixes updating the sourcemap comment to point to the right file. It also updates the test to use esbuild instead of webpack as the sourcemaps generated by esbuild are friendlier without webpack speicif protocol representing files. As we move to esbuild, the existing webpack plugin is modified to suit esbuild as well. Signed-off-by: Karthik Ganeshram <[email protected]>
1 parent 6ebf68f commit 242d361

File tree

7 files changed

+661
-612
lines changed

7 files changed

+661
-612
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {
2+
getPackagesWithWasiDeps,
3+
processWasiDeps
4+
} from '../../dist/wasiDepsParser.js';
5+
6+
export async function SpinEsbuildPlugin() {
7+
const { getWitImports } = await import('../../lib/wit_tools.js');
8+
9+
// Step 1: Get WIT imports from dependencies
10+
const wasiDeps = getPackagesWithWasiDeps(process.cwd(), new Set(), true);
11+
const { witPaths, targetWorlds } = processWasiDeps(wasiDeps);
12+
const witImports = getWitImports(witPaths, targetWorlds);
13+
14+
// Store as a Set for fast lookup
15+
const externals = new Set(witImports);
16+
17+
return {
18+
name: 'spin-sdk-externals',
19+
setup(build) {
20+
build.onResolve({ filter: /.*/ }, args => {
21+
if (externals.has(args.path)) {
22+
return { path: args.path, external: true };
23+
}
24+
return null;
25+
});
26+
}
27+
};
28+
}

packages/build-tools/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ async function main() {
7070
const source = await readFile(src, 'utf8');
7171
let { content: precompiledSource, sourceMap: precompiledSourceMap } = precompile(source, src, true, 'precompiled-source.js') as { content: string; sourceMap: SourceMapInput };
7272
// Check if input file has a source map because if we does, we need to chain it with the precompiled source map
73+
// TODO: check using the sourcemap comment instead of the file existence and also deal with base64 encoded source maps
7374
if (await fileExists(src + '.map')) {
7475
const inputSourceMap = JSON.parse(await readFile(src + '.map', 'utf8')) as SourceMapInput;
75-
precompiledSourceMap = chainSourceMaps(precompiledSourceMap, { src: inputSourceMap }) as SourceMapInput;
76+
precompiledSourceMap = chainSourceMaps(precompiledSourceMap, { [src]: inputSourceMap }) as SourceMapInput;
7677
}
7778

7879
// Write precompiled source to disk for debugging purposes.

packages/build-tools/src/precompile.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,23 @@ export function precompile(source, filename = '<input>', moduleMode = false, pre
5151

5252
magicString.prepend(`${PREAMBLE}${precompileCalls.join('\n')}${POSTAMBLE}`);
5353

54+
const sourceMapRegex = /\/\/# sourceMappingURL=.*$/gm;
55+
56+
let match;
57+
while ((match = sourceMapRegex.exec(source))) {
58+
const start = match.index;
59+
const end = start + match[0].length;
60+
magicString.remove(start, end);
61+
}
62+
63+
const precompiledSource = magicString.toString() + `\n//# sourceMappingURL=${precompiledFileName}.map\n`;
64+
5465
// When we're ready to pipe in source maps:
5566
const map = magicString.generateMap({
5667
source: filename,
5768
file: `${precompiledFileName}.map`,
5869
includeContent: true
5970
});
6071

61-
return { content: magicString.toString(), sourceMap: map };
72+
return { content: precompiledSource, sourceMap: map };
6273
}

test/test-app/build.mjs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// build.mjs
2+
import { build } from 'esbuild';
3+
import path from 'path';
4+
import { SpinEsbuildPlugin } from "@spinframework/build-tools/plugins/esbuild/index.js";
5+
import fs from 'fs';
6+
7+
const spinPlugin = await SpinEsbuildPlugin();
8+
9+
let SourceMapPlugin = {
10+
name: 'excludeVendorFromSourceMap',
11+
setup(build) {
12+
build.onLoad({ filter: /node_modules/ }, args => {
13+
return {
14+
contents: fs.readFileSync(args.path, 'utf8')
15+
+ '\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==',
16+
loader: 'default',
17+
}
18+
})
19+
},
20+
}
21+
22+
await build({
23+
entryPoints: ['./src/index.ts'],
24+
outfile: './build/bundle.js',
25+
bundle: true,
26+
format: 'esm',
27+
platform: 'node',
28+
sourcemap: true,
29+
minify: false,
30+
plugins: [spinPlugin, SourceMapPlugin],
31+
logLevel: 'error',
32+
loader: {
33+
'.ts': 'ts',
34+
'.tsx': 'tsx',
35+
},
36+
resolveExtensions: ['.ts', '.tsx', '.js'],
37+
// This prevents sourcemaps from traversing into node_modules
38+
sourceRoot: path.resolve(process.cwd(), 'src'),
39+
});

0 commit comments

Comments
 (0)