Skip to content
This repository was archived by the owner on Oct 18, 2023. It is now read-only.

Commit 1acd7fd

Browse files
committed
perf: handle source map as object (#35)
BREAKING CHANGE: applyTransformers returns source map as object
1 parent 3211965 commit 1acd7fd

File tree

7 files changed

+53
-59
lines changed

7 files changed

+53
-59
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"manten": "^0.3.0",
5252
"memfs": "^3.4.7",
5353
"pkgroll": "^1.4.0",
54+
"source-map": "^0.6.0",
5455
"tsx": "^3.9.0",
5556
"typescript": "^4.8.4"
5657
},

pnpm-lock.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/source-map.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sourceMapSupport from 'source-map-support';
2-
import type { SourceMapInput } from '@ampproject/remapping';
2+
import type { RawSourceMap } from 'source-map';
3+
import type { Transformed } from './transform/apply-transformers';
34

45
const inlineSourceMapPrefix = '\n//# sourceMappingURL=data:application/json;base64,';
56

@@ -25,14 +26,15 @@ export function installSourceMapSupport() {
2526
process.setSourceMapsEnabled(true);
2627

2728
return (
28-
{ code, map }: { code: string; map: SourceMapInput },
29-
) => {
30-
const mapString = typeof map === 'string' ? map : map.toString();
31-
return code + inlineSourceMapPrefix + Buffer.from(mapString, 'utf8').toString('base64');
32-
};
29+
{ code, map }: Transformed,
30+
) => (
31+
code
32+
+ inlineSourceMapPrefix
33+
+ Buffer.from(JSON.stringify(map), 'utf8').toString('base64')
34+
);
3335
}
3436

35-
const sourcemaps = new Map<string, string>();
37+
const sourcemaps = new Map<string, RawSourceMap>();
3638

3739
sourceMapSupport.install({
3840
environment: 'node',
@@ -43,11 +45,10 @@ export function installSourceMapSupport() {
4345
});
4446

4547
return (
46-
{ code, map }: { code: string; map: SourceMapInput },
48+
{ code, map }: Transformed,
4749
filePath: string,
4850
) => {
49-
const mapString = typeof map === 'string' ? map : map.toString();
50-
sourcemaps.set(filePath, mapString);
51+
sourcemaps.set(filePath, map);
5152
return code;
5253
};
5354
}
Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import remapping from '@ampproject/remapping';
22
import type { SourceMapInput } from '@ampproject/remapping';
3+
import type { RawSourceMap } from 'source-map';
4+
5+
type SourceMap = SourceMapInput | RawSourceMap;
36

47
type MaybePromise<T> = T | Promise<T>;
58

@@ -9,19 +12,17 @@ type IntersectionArray<T extends unknown[]> = (
912
: unknown
1013
);
1114

12-
type Transformed = {
15+
type TransformerResult = {
1316
code: string;
14-
map: SourceMapInput;
15-
};
16-
17-
type TransformerResult = Transformed | undefined;
17+
map: SourceMap;
18+
} | undefined;
1819

1920
type Transformer<
20-
Result extends MaybePromise<TransformerResult>
21+
ReturnType extends MaybePromise<TransformerResult>
2122
> = (
2223
filePath: string,
2324
code: string,
24-
) => Result;
25+
) => ReturnType;
2526

2627
type Results<
2728
Array_ extends Transformer<MaybePromise<TransformerResult>>[]
@@ -33,7 +34,12 @@ type Results<
3334
);
3435
};
3536

36-
type AddSourceMap<T> = Omit<T, 'map'> & { map: string };
37+
type AddSourceMap<T> = Omit<T, 'map'> & { map: RawSourceMap };
38+
39+
export type Transformed = {
40+
code: string;
41+
map: RawSourceMap;
42+
};
3743

3844
export function applyTransformersSync<
3945
T extends Readonly<Transformer<TransformerResult>[]>,
@@ -42,11 +48,8 @@ export function applyTransformersSync<
4248
code: string,
4349
transformers: T,
4450
) {
45-
const maps: SourceMapInput[] = [];
46-
const result = {
47-
code,
48-
map: '',
49-
};
51+
const maps: SourceMap[] = [];
52+
const result = { code };
5053

5154
for (const transformer of transformers) {
5255
const transformed = transformer(filePath, result.code);
@@ -57,13 +60,10 @@ export function applyTransformersSync<
5760
}
5861
}
5962

60-
result.map = (
61-
maps.length > 1
62-
? remapping(maps, () => null).toString()
63-
: maps[0].toString()
64-
);
65-
66-
return result as unknown as AddSourceMap<IntersectionArray<Results<[...T]>>>;
63+
return {
64+
...result,
65+
map: remapping(maps as SourceMapInput[], () => null),
66+
} as unknown as AddSourceMap<IntersectionArray<Results<[...T]>>>;
6767
}
6868

6969
export async function applyTransformers<
@@ -73,11 +73,8 @@ export async function applyTransformers<
7373
code: string,
7474
transformers: T,
7575
) {
76-
const maps: SourceMapInput[] = [];
77-
const result = {
78-
code,
79-
map: '',
80-
};
76+
const maps: SourceMap[] = [];
77+
const result = { code };
8178

8279
for (const transformer of transformers) {
8380
const transformed = await transformer(filePath, result.code);
@@ -88,11 +85,8 @@ export async function applyTransformers<
8885
}
8986
}
9087

91-
result.map = (
92-
maps.length > 1
93-
? remapping(maps, () => null).toString()
94-
: maps[0].toString()
95-
);
96-
97-
return result as unknown as AddSourceMap<IntersectionArray<Results<[...T]>>>;
88+
return {
89+
...result,
90+
map: remapping(maps as SourceMapInput[], () => null),
91+
} as unknown as AddSourceMap<IntersectionArray<Results<[...T]>>>;
9892
}

src/transform/cache.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import fs from 'fs';
22
import path from 'path';
33
import os from 'os';
4-
import type { TransformResult } from 'esbuild';
54
import { readJsonFile } from '../utils/read-json-file';
5+
import type { Transformed } from './apply-transformers';
66

77
const getTime = () => Math.floor(Date.now() / 1e8);
88

9-
class FileCache extends Map<string, TransformResult> {
9+
class FileCache<ReturnType> extends Map<string, ReturnType> {
1010
/**
1111
* By using tmpdir, the expectation is for the OS to clean any files
1212
* that haven't been read for a while.
@@ -56,7 +56,7 @@ class FileCache extends Map<string, TransformResult> {
5656
}
5757

5858
const cacheFilePath = path.join(this.cacheDirectory, diskCacheHit.fileName);
59-
const cachedResult = readJsonFile<TransformResult>(cacheFilePath);
59+
const cachedResult = readJsonFile<ReturnType>(cacheFilePath);
6060

6161
if (!cachedResult) {
6262
// Remove broken cache file
@@ -77,7 +77,7 @@ class FileCache extends Map<string, TransformResult> {
7777
return cachedResult;
7878
}
7979

80-
set(key: string, value: TransformResult) {
80+
set(key: string, value: ReturnType) {
8181
super.set(key, value);
8282

8383
if (value) {
@@ -116,6 +116,6 @@ class FileCache extends Map<string, TransformResult> {
116116

117117
export default (
118118
process.env.ESBK_DISABLE_CACHE
119-
? new Map<string, TransformResult>()
120-
: new FileCache()
119+
? new Map<string, Transformed>()
120+
: new FileCache<Transformed>()
121121
);

src/transform/index.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@ import {
88
import { sha1 } from '../utils/sha1';
99
import { transformDynamicImport } from './transform-dynamic-import';
1010
import cache from './cache';
11-
import { applyTransformersSync, applyTransformers } from './apply-transformers';
11+
import {
12+
applyTransformersSync,
13+
applyTransformers,
14+
type Transformed,
15+
} from './apply-transformers';
1216
import { getEsbuildOptions } from './get-esbuild-options';
1317

1418
export { transformDynamicImport } from './transform-dynamic-import';
1519

16-
type Transformed = {
17-
code: string;
18-
map: string;
19-
};
20-
2120
// Used by cjs-loader
2221
export function transformSync(
2322
code: string,

src/transform/transform-dynamic-import.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import MagicString from 'magic-string';
2-
import type { EncodedSourceMap } from '@ampproject/remapping';
2+
import type { RawSourceMap } from 'source-map';
33
import { parseEsm } from '../utils/es-module-lexer';
44

5-
// Necessary for types to build correctly
6-
export type { EncodedSourceMap };
7-
85
const checkEsModule = `.then((mod)=>{
96
const exports = Object.keys(mod);
107
if(
@@ -41,6 +38,6 @@ export function transformDynamicImport(
4138
map: magicString.generateMap({
4239
source: filePath,
4340
hires: true,
44-
}) as EncodedSourceMap,
41+
}) as unknown as RawSourceMap,
4542
};
4643
}

0 commit comments

Comments
 (0)