Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions packages/angular/build/src/tools/angular/linker/oxc-linker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import type { EncodedSourceMap } from '@ampproject/remapping';
import type { DecodedSourceMap } from '@ampproject/remapping';
import remapping from '@ampproject/remapping';
import { ConsoleLogger, LogLevel } from '@angular/compiler-cli';
import type { DeclarationScope } from '@angular/compiler-cli/linker';
Expand Down Expand Up @@ -170,12 +170,15 @@ export function linkWithOxc(filename: string, code: string, options: OxcLinkerOp

let map: string | undefined;
if (options.sourcemap) {
const rawMap = s.generateMap({ hires: true, source: filename });
const inputMap = loadInputSourceMap(filename, code);
if (inputMap) {
map = remapping([rawMap as EncodedSourceMap, inputMap], () => null).toString();
const rawMap = s.generateDecodedMap({ hires: true, source: filename });
map = remapping(
[{ ...rawMap, version: 3 } satisfies DecodedSourceMap, inputMap],
() => null,
).toString();
} else {
map = rawMap.toString();
map = s.generateMap({ hires: true, source: filename }).toString();
}
}

Expand Down
49 changes: 49 additions & 0 deletions packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,53 @@ describe('linkWithOxc', () => {
expect(result.code).toContain('i0.ɵɵdefineComponent');
expect(result.code).not.toContain('i0.ɵɵngDeclareComponent');
});

it('should generate a sourcemap when sourcemap option is enabled', () => {
const input = `
import * as i0 from "@angular/core";
export class MyDirective {}
MyDirective.ɵdir = i0.ɵɵngDeclareDirective({
minVersion: "12.0.0",
version: "14.0.0",
ngImport: i0,
type: MyDirective,
selector: "[my-dir]"
});
`;

const result = linkWithOxc('test.js', input, { sourcemap: true });
expect(result.map).toBeDefined();
const parsedMap = JSON.parse(result.map as string);
expect(parsedMap.version).toBe(3);
expect(parsedMap.sources).toContain('test.js');
});

it('should remap with input sourcemap when sourcemap option is enabled and inputMap is present', () => {
const inputMap = {
version: 3,
sources: ['original.ts'],
sourcesContent: ['// original content'],
mappings: 'AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA',
names: [],
};
const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64');
const input = `
import * as i0 from "@angular/core";
export class MyDirective {}
MyDirective.ɵdir = i0.ɵɵngDeclareDirective({
minVersion: "12.0.0",
version: "14.0.0",
ngImport: i0,
type: MyDirective,
selector: "[my-dir]"
});
//# sourceMappingURL=data:application/json;base64,${base64Map}
`;

const result = linkWithOxc('test.js', input, { sourcemap: true });
expect(result.map).toBeDefined();
const parsedMap = JSON.parse(result.map as string);
expect(parsedMap.version).toBe(3);
expect(parsedMap.sources).toContain('original.ts');
});
});
11 changes: 7 additions & 4 deletions packages/angular/build/src/tools/oxc/oxc-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import remapping, { type EncodedSourceMap } from '@ampproject/remapping';
import remapping, { type DecodedSourceMap } from '@ampproject/remapping';
import type { BindingIdentifier, Class, Node } from '@oxc-project/types';
import { MagicString } from 'magic-string';
import { Visitor, parseSync } from 'oxc-parser';
Expand Down Expand Up @@ -749,13 +749,16 @@ export function transform(filename: string, code: string, options: OxcTransformO

let map: string | undefined;
if (options.sourcemap) {
const rawMap = s.generateMap({ hires: true, source: filename });
const inputMap = loadInputSourceMap(filename, code);

if (inputMap) {
map = remapping([rawMap as EncodedSourceMap, inputMap], () => null).toString();
const rawMap = s.generateDecodedMap({ hires: true, source: filename });
map = remapping(
[{ ...rawMap, version: 3 } satisfies DecodedSourceMap, inputMap],
() => null,
).toString();
} else {
map = rawMap.toString();
map = s.generateMap({ hires: true, source: filename }).toString();
}
}

Expand Down
42 changes: 42 additions & 0 deletions packages/angular/build/src/tools/oxc/oxc-transform_spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/

import { transform } from './oxc-transform';

describe('oxc-transform sourcemaps', () => {
it('should generate a sourcemap when sourcemap option is enabled without inputMap', () => {
const input = 'var result = new SomeClass();';
const result = transform('test.js', input, { sourcemap: true });

expect(result.map).toBeDefined();
const parsedMap = JSON.parse(result.map as string);
expect(parsedMap.version).toBe(3);
expect(parsedMap.sources).toContain('test.js');
expect(parsedMap.mappings.length).toBeGreaterThan(0);
});

it('should remap with input sourcemap when sourcemap option is enabled and inputMap is present', () => {
const inputMap = {
version: 3,
sources: ['original.ts'],
sourcesContent: ['const result = new SomeClass();'],
mappings: 'AAAA',
names: [],
};
const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64');
const input = `var result = new SomeClass();\n//# sourceMappingURL=data:application/json;base64,${base64Map}`;

const result = transform('test.js', input, { sourcemap: true });

expect(result.map).toBeDefined();
const parsedMap = JSON.parse(result.map as string);
expect(parsedMap.version).toBe(3);
expect(parsedMap.sources).toContain('original.ts');
expect(parsedMap.mappings.length).toBeGreaterThan(0);
});
});
17 changes: 10 additions & 7 deletions packages/angular/build/src/tools/sass/rebasing-importer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import { RawSourceMap } from '@ampproject/remapping';
import type { DecodedSourceMap } from '@ampproject/remapping';
import { MagicString } from 'magic-string';
import { readFileSync, readdirSync, statSync } from 'node:fs';
import { basename, dirname, extname, join, relative } from 'node:path';
Expand Down Expand Up @@ -44,7 +44,7 @@ abstract class UrlRebasingImporter implements Importer<'sync'> {
*/
constructor(
private entryDirectory: string,
private rebaseSourceMaps?: Map<string, RawSourceMap>,
private rebaseSourceMaps?: Map<string, DecodedSourceMap>,
) {}

abstract canonicalize(url: string, options: { fromImport: boolean }): URL | null;
Expand Down Expand Up @@ -95,12 +95,15 @@ abstract class UrlRebasingImporter implements Importer<'sync'> {
contents = updatedContents.toString();
if (this.rebaseSourceMaps) {
// Generate an intermediate source map for the rebasing changes
const map = updatedContents.generateMap({
const map = updatedContents.generateDecodedMap({
hires: 'boundary',
includeContent: true,
source: canonicalUrl.href,
});
this.rebaseSourceMaps.set(canonicalUrl.href, map as RawSourceMap);
this.rebaseSourceMaps.set(canonicalUrl.href, {
...map,
version: 3,
} satisfies DecodedSourceMap);
}
}

Expand Down Expand Up @@ -134,7 +137,7 @@ export class RelativeUrlRebasingImporter extends UrlRebasingImporter {
constructor(
entryDirectory: string,
private directoryCache = new Map<string, DirectoryEntry>(),
rebaseSourceMaps?: Map<string, RawSourceMap>,
rebaseSourceMaps?: Map<string, DecodedSourceMap>,
) {
super(entryDirectory, rebaseSourceMaps);
}
Expand Down Expand Up @@ -322,7 +325,7 @@ export class ModuleUrlRebasingImporter extends RelativeUrlRebasingImporter {
constructor(
entryDirectory: string,
directoryCache: Map<string, DirectoryEntry>,
rebaseSourceMaps: Map<string, RawSourceMap> | undefined,
rebaseSourceMaps: Map<string, DecodedSourceMap> | undefined,
private finder: (specifier: string, options: CanonicalizeContext) => URL | null,
) {
super(entryDirectory, directoryCache, rebaseSourceMaps);
Expand All @@ -349,7 +352,7 @@ export class LoadPathsUrlRebasingImporter extends RelativeUrlRebasingImporter {
constructor(
entryDirectory: string,
directoryCache: Map<string, DirectoryEntry>,
rebaseSourceMaps: Map<string, RawSourceMap> | undefined,
rebaseSourceMaps: Map<string, DecodedSourceMap> | undefined,
private loadPaths: Iterable<string>,
) {
super(entryDirectory, directoryCache, rebaseSourceMaps);
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/build/src/tools/sass/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import mergeSourceMaps, { RawSourceMap } from '@ampproject/remapping';
import mergeSourceMaps, { type DecodedSourceMap, type RawSourceMap } from '@ampproject/remapping';
import { dirname } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { MessagePort, receiveMessageOnPort } from 'node:worker_threads';
Expand Down Expand Up @@ -89,7 +89,7 @@ export default async function renderSassStylesheet(
let warnings: SerializableWarningMessage[] | undefined;
try {
const directoryCache = new Map<string, DirectoryEntry>();
const rebaseSourceMaps = options.sourceMap ? new Map<string, RawSourceMap>() : undefined;
const rebaseSourceMaps = options.sourceMap ? new Map<string, DecodedSourceMap>() : undefined;
if (importerChannel) {
// When a custom importer function is present, the importer request must be proxied
// back to the main thread where it can be executed.
Expand Down