diff --git a/packages/typegpu/src/shared/normalizeMetadata.ts b/packages/typegpu/src/shared/normalizeMetadata.ts index 3ef2fe0456..2398577217 100644 --- a/packages/typegpu/src/shared/normalizeMetadata.ts +++ b/packages/typegpu/src/shared/normalizeMetadata.ts @@ -15,6 +15,7 @@ export interface RawMetadataV2 { name: string; ast: { params: FuncParameter[]; body: Block | SourceMappedNode }; externals: { [key: string]: () => unknown }; + filename?: string; } /** @@ -28,6 +29,7 @@ export type RawMetadata = RawMetadataV1 | RawMetadataV2; export interface Metadata { ast: { params: FuncParameter[]; body: Block | SourceMappedNode }; externals: () => Record; + filename?: string; } /** diff --git a/packages/unplugin-typegpu/src/babel.ts b/packages/unplugin-typegpu/src/babel.ts index 614e4d60a8..30245ace7e 100644 --- a/packages/unplugin-typegpu/src/babel.ts +++ b/packages/unplugin-typegpu/src/babel.ts @@ -51,6 +51,9 @@ function assignMetadata( t.objectProperty(i('name'), t.valueToNode(name)), t.objectProperty(i('ast'), t.valueToNode({ params: ast.params, body: ast.body })), t.objectProperty(i('externals'), externalsToNode(ast.externalNames)), + ...(this.opts.unstable_sourceMaps && this.filename + ? [t.objectProperty(i('filename'), t.stringLiteral(this.filename))] + : []), ]); let expression: t.Expression; diff --git a/packages/unplugin-typegpu/src/core/factory.ts b/packages/unplugin-typegpu/src/core/factory.ts index eed1a33e4a..26d70e9895 100644 --- a/packages/unplugin-typegpu/src/core/factory.ts +++ b/packages/unplugin-typegpu/src/core/factory.ts @@ -58,7 +58,11 @@ function assignMetadata( v: ${METADATA_FORMAT_VERSION}, name: ${name ? `"${name}"` : 'undefined'}, ast: ${embedJSON({ params: ast.params, body: ast.body })}, - externals: ${externalsToString(ast.externalNames)} + externals: ${externalsToString(ast.externalNames)}${ + this.opts.unstable_sourceMaps && this.filename + ? `,\n filename: ${embedJSON(this.filename)}` + : '' + } }`; const visibility = t.isFunctionDeclaration(path.node) @@ -262,7 +266,7 @@ export const unpluginFactory = ((rawOptions, _meta) => { return magicString.generateMap({ source: id, includeContent: true, - hires: 'boundary', + hires: options.unstable_sourceMaps ? true : 'boundary', }); }, }; diff --git a/packages/unplugin-typegpu/test/sourceMaps.test.ts b/packages/unplugin-typegpu/test/sourceMaps.test.ts index 7b02a747c3..bc8aa82b8e 100644 --- a/packages/unplugin-typegpu/test/sourceMaps.test.ts +++ b/packages/unplugin-typegpu/test/sourceMaps.test.ts @@ -99,8 +99,7 @@ describe('source maps', () => { test('[BABEL]', () => { const transformed = babelTransform(code, { unstable_sourceMaps: true }); - expect(transformed).toMatchInlineSnapshot( - ` + expect(transformed).toMatchInlineSnapshot(` "import { tgpu } from 'typegpu'; const external = { n: 1 @@ -124,8 +123,7 @@ describe('source maps', () => { "external.n": () => external.n } }) && $.f)({});" - `, - ); + `); }); test('[ROLLUP]', async () => { @@ -145,7 +143,8 @@ describe('source maps', () => { v: 2, name: "fn", ast: {"params":[{"type":"i","name":"argument"}],"body":[-1,5,38,[0,[[-1,7,8,[13,[-1,7,14,[9,"variable"]],[-1,7,25,[5,"3"]]]],[-1,8,8,[10,[-1,8,15,[1,[-1,8,15,[1,[-1,8,15,[9,"external.n"]],"+",[-1,8,28,[9,"argument"]]]],"+",[-1,8,39,[9,"variable"]]]]]]]]]}, - externals: {"external.n":() => external.n} + externals: {"external.n":() => external.n}, + filename: "\\u0000virtual:code" }) && $.f)({})); export { fn }; @@ -302,4 +301,34 @@ describe('source maps', () => { }); }); }); + + describe('file name', () => { + const code = `const fn = () => { 'use gpu'; return 1; }; console.log(fn)`; + + describe('is included when source maps are enabled', () => { + test('[BABEL]', () => { + const transformed = babelTransform(code, { unstable_sourceMaps: true }, [], [], 'test.ts'); + const filename = transformed?.match(/.*filename(.*)\n/)?.[1]; + expect(filename).toMatchInlineSnapshot(`": "/test.ts""`); + }); + + test('[ROLLUP]', async () => { + const transformed = await rollupTransform(code, { unstable_sourceMaps: true }); + const filename = transformed?.match(/.*filename(.*)\n/)?.[1]; + expect(filename).toMatchInlineSnapshot(`": "\\u0000virtual:code""`); + }); + }); + + describe('is omitted when source maps are disabled', () => { + test('[BABEL]', () => { + const transformed = babelTransform(code, { unstable_sourceMaps: false }, [], [], 'test.ts'); + expect(transformed).not.toContain('filename:'); + }); + + test('[ROLLUP]', async () => { + const transformed = await rollupTransform(code, { unstable_sourceMaps: false }); + expect(transformed).not.toContain('filename:'); + }); + }); + }); }); diff --git a/packages/unplugin-typegpu/test/transform.ts b/packages/unplugin-typegpu/test/transform.ts index 97dadf0093..36a2cc39f1 100644 --- a/packages/unplugin-typegpu/test/transform.ts +++ b/packages/unplugin-typegpu/test/transform.ts @@ -25,8 +25,10 @@ export const babelTransform = ( options?: Options, prePlugins: BabelTestPlugin[] = [], postPlugins: BabelTestPlugin[] = [], + filename?: string, ) => Babel.transform(code, { + filename, plugins: [...prePlugins, [babelPlugin, { ...defaultOptions, ...options }], ...postPlugins], parserOpts: { plugins: ['typescript'] }, }).code;