Skip to content

Commit f9b87f6

Browse files
committed
add: import decoded sourcemaps from SourceMapGenerator
1 parent 910348f commit f9b87f6

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

src/compiler/preprocess/index.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { RawSourceMap, DecodedSourceMap } from '@ampproject/remapping/dist/types
22
import { decode as decode_mappings } from 'sourcemap-codec';
33
import { getLocator } from 'locate-character';
44
import { StringWithSourcemap, sourcemap_add_offset, combine_sourcemaps } from '../utils/string_with_sourcemap';
5+
import { compareByGeneratedPositionsInflated } from 'source-map/lib/util';
56

67
export interface Processed {
78
code: string;
@@ -83,6 +84,72 @@ async function replace_async(
8384
return out.concat(final_content);
8485
}
8586

87+
88+
89+
// import decoded sourcemap from mozilla/source-map/SourceMapGenerator
90+
// forked from source-map/lib/source-map-generator.js
91+
// from methods _serializeMappings and toJSON
92+
function DecodedSourcemapFromSourceMapGenerator(this: any) {
93+
function convertMappings(this: any) {
94+
let previousGeneratedLine = 1;
95+
let result = [[]];
96+
let resultLine;
97+
let resultSegment;
98+
let mapping;
99+
100+
const sourceIdx = this._sources.toArray().reduce((acc, val, idx) => (acc[val] = idx, acc), {});
101+
const nameIdx = this._names.toArray().reduce((acc, val, idx) => (acc[val] = idx, acc), {});
102+
103+
const mappings = this._mappings.toArray();
104+
resultLine = result[0];
105+
106+
for (let i = 0, len = mappings.length; i < len; i++) {
107+
mapping = mappings[i];
108+
109+
if (mapping.generatedLine > previousGeneratedLine) {
110+
while (mapping.generatedLine > previousGeneratedLine) {
111+
result.push([]);
112+
previousGeneratedLine++;
113+
}
114+
resultLine = result[mapping.generatedLine - 1]; // line is one-based
115+
} else if (i > 0) {
116+
if (
117+
!compareByGeneratedPositionsInflated(mapping, mappings[i - 1])
118+
) {
119+
continue;
120+
}
121+
}
122+
resultLine.push([mapping.generatedColumn]);
123+
resultSegment = resultLine[resultLine.length - 1];
124+
125+
if (mapping.source != null) {
126+
resultSegment.push(...[
127+
sourceIdx[mapping.source],
128+
mapping.originalLine - 1, // line is one-based
129+
mapping.originalColumn
130+
]);
131+
if (mapping.name != null) {
132+
resultSegment.push(nameIdx[mapping.name]);
133+
}
134+
}
135+
}
136+
return result;
137+
}
138+
const map = {
139+
version: this._version,
140+
sources: this._sources.toArray(),
141+
names: this._names.toArray(),
142+
mappings: convertMappings.apply(this)
143+
};
144+
if (this._file != null) {
145+
(map as any).file = this._file;
146+
}
147+
// not needed: map.sourcesContent and map.sourceRoot
148+
return map;
149+
}
150+
151+
152+
86153
/**
87154
* Convert a preprocessor output and its leading prefix and trailing suffix into StringWithSourceMap
88155
*/
@@ -109,6 +176,13 @@ function get_replacement(
109176
if (typeof(decoded_map.mappings) === 'string') {
110177
decoded_map.mappings = decode_mappings(decoded_map.mappings);
111178
}
179+
if (
180+
(decoded_map as any)._mappings &&
181+
decoded_map.constructor.name == 'SourceMapGenerator'
182+
) {
183+
// import decoded sourcemap from mozilla/source-map/SourceMapGenerator
184+
decoded_map = DecodedSourcemapFromSourceMapGenerator.apply(decoded_map);
185+
}
112186
sourcemap_add_offset(decoded_map, get_location(offset + prefix.length));
113187
}
114188
const processed_with_map = StringWithSourcemap.from_processed(processed.code, decoded_map);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import MagicString from 'magic-string';
2+
import { SourceMapConsumer, SourceMapGenerator } from 'source-map';
3+
import { getLocator } from 'locate-character';
4+
5+
export default {
6+
preprocess: {
7+
style: async ({ content, filename }) => {
8+
const src = new MagicString(content);
9+
const idx = content.indexOf("baritone");
10+
src.overwrite(idx, idx+"baritone".length, "bar");
11+
12+
const map = SourceMapGenerator.fromSourceMap(
13+
await new SourceMapConsumer(
14+
// sourcemap must be encoded for SourceMapConsumer
15+
src.generateMap({
16+
source: filename,
17+
hires: true,
18+
includeContent: false
19+
})
20+
)
21+
);
22+
23+
return { code: src.toString(), map };
24+
}
25+
}
26+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h1>Testing Styles</h1>
2+
<h2>Testing Styles 2</h2>
3+
<script>export const b = 2;</script>
4+
<style>
5+
h1 {
6+
--baritone: red;
7+
}
8+
9+
h2 {
10+
--baz: blue;
11+
}
12+
</style>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { test } from '../preprocessed-styles/test'

0 commit comments

Comments
 (0)