Skip to content

Commit d5bac48

Browse files
authored
feat(terser): support source map files (#1195)
1 parent 66d9a40 commit d5bac48

7 files changed

Lines changed: 80 additions & 7 deletions

File tree

packages/terser/src/terser_minified.bzl

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Can be a .js file, a rule producing .js files as its default output, or a rule p
4040
4141
Note that you can pass multiple files to terser, which it will bundle together.
4242
If you want to do this, you can pass a filegroup here.""",
43-
allow_files = [".js"],
43+
allow_files = [".js", ".map", ".mjs"],
4444
mandatory = True,
4545
),
4646
"config_file": attr.label(
@@ -95,6 +95,9 @@ so that it only affects the current build.
9595
),
9696
}
9797

98+
def _filter_js(files):
99+
return [f for f in files if f.is_directory or f.extension == "js" or f.extension == "mjs"]
100+
98101
def _terser(ctx):
99102
"Generate actions to create terser config run terser"
100103

@@ -103,17 +106,19 @@ def _terser(ctx):
103106
inputs = ctx.files.src[:]
104107
outputs = []
105108

106-
directory_srcs = [s for s in ctx.files.src if s.is_directory]
109+
sources = _filter_js(inputs)
110+
sourcemaps = [f for f in inputs if f.extension == "map"]
111+
directory_srcs = [s for s in sources if s.is_directory]
107112
if len(directory_srcs) > 0:
108-
if len(ctx.files.src) > 1:
113+
if len(sources) > 1:
109114
fail("When directories are passed to terser_minified, there should be only one input")
110115
outputs.append(ctx.actions.declare_directory(ctx.label.name))
111116
else:
112117
outputs.append(ctx.actions.declare_file("%s.js" % ctx.label.name))
113118
if ctx.attr.sourcemap:
114119
outputs.append(ctx.actions.declare_file("%s.js.map" % ctx.label.name))
115120

116-
args.add_all([s.path for s in ctx.files.src])
121+
args.add_all([s.path for s in sources])
117122
args.add_all(["--output", outputs[0].path])
118123

119124
debug = ctx.attr.debug or "DEBUG" in ctx.var.keys()
@@ -126,9 +131,12 @@ def _terser(ctx):
126131
# see https://github.com/terser-js/terser#command-line-usage
127132
source_map_opts = ["includeSources", "base=" + ctx.bin_dir.path]
128133

129-
# We support only inline sourcemaps for now.
130-
# It's hard to pair up the .js inputs with corresponding .map files
131-
source_map_opts.append("content=inline")
134+
if len(sourcemaps) == 0:
135+
source_map_opts.append("content=inline")
136+
elif len(sourcemaps) == 1:
137+
source_map_opts.append("content='%s'" % sourcemaps[0].path)
138+
else:
139+
fail("When sourcemap is True, there should only be one or none input sourcemaps")
132140

133141
# This option doesn't work in the config file, only on the CLI
134142
args.add_all(["--source-map", ",".join(source_map_opts)])
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
load("@npm_bazel_jasmine//:index.from_src.bzl", "jasmine_node_test")
2+
load("@npm_bazel_terser//:index.from_src.bzl", "terser_minified")
3+
4+
filegroup(
5+
name = "src1_and_map",
6+
srcs = [
7+
"src1.js",
8+
"src1.js.map",
9+
],
10+
)
11+
12+
terser_minified(
13+
name = "src1.min",
14+
src = ":src1_and_map",
15+
)
16+
17+
jasmine_node_test(
18+
name = "test",
19+
srcs = [
20+
"terser_spec.js",
21+
],
22+
data = ["@npm//source-map"],
23+
deps = [
24+
":src1.min",
25+
],
26+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The src1.js{,.map} files were generated from running `tsc --lib es2015,dom --sourcemap --noImplicitUseStrict src1.ts`.

packages/terser/test/sourcemap/src1.js

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

packages/terser/test/sourcemap/src1.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// clang-format off
2+
/*a comment*/ export class MyClass {
3+
constructor(s: string) {
4+
console.log(s);
5+
}
6+
field: string|undefined;
7+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const fs = require('fs');
2+
const sm = require('source-map');
3+
const DIR = 'build_bazel_rules_nodejs/packages/terser/test/sourcemap';
4+
5+
describe('terser sourcemap handling', () => {
6+
it('should produce a sourcemap output', async () => {
7+
const file = require.resolve(DIR + '/src1.min.js.map');
8+
const rawSourceMap = JSON.parse(fs.readFileSync(file, 'utf-8'));
9+
await sm.SourceMapConsumer.with(rawSourceMap, null, consumer => {
10+
const pos = consumer.originalPositionFor(
11+
// position of MyClass in terser_minified output src1.min.js
12+
// depends on DEBUG flag
13+
!process.env['DEBUG'] ? {line: 1, column: 18} : {line: 3, column: 5});
14+
expect(pos.source).toBe('src1.ts');
15+
expect(pos.line).toBe(2);
16+
expect(pos.column).toBe(14);
17+
expect(pos.name).toBe('MyClass');
18+
});
19+
});
20+
});

0 commit comments

Comments
 (0)