Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(esbuild): add 'sourcemap' option to configure sourcemap generation #2528

Merged
merged 4 commits into from
Mar 18, 2021
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
28 changes: 25 additions & 3 deletions packages/esbuild/esbuild.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ def _esbuild_impl(ctx):
args = ctx.actions.args()

args.add("--bundle", entry_point.path)
args.add("--sourcemap")

if len(ctx.attr.sourcemap) > 0:
args.add_joined(["--sourcemap", ctx.attr.sourcemap], join_with = "=")
else:
args.add("--sourcemap")

args.add("--preserve-symlinks")
args.add_joined(["--platform", ctx.attr.platform], join_with = "=")
args.add_joined(["--target", ctx.attr.target], join_with = "=")
Expand Down Expand Up @@ -87,8 +92,13 @@ def _esbuild_impl(ctx):
args.add_joined(["--outdir", js_out.path], join_with = "=")
else:
js_out = ctx.outputs.output
outputs.append(js_out)

js_out_map = ctx.outputs.output_map
outputs.extend([js_out, js_out_map])
if ctx.attr.sourcemap != "inline":
if js_out_map == None:
fail("output_map must be specified if sourcemap is not set to 'inline'")
outputs.append(js_out_map)

if ctx.attr.format:
args.add_joined(["--format", ctx.attr.format], join_with = "=")
Expand Down Expand Up @@ -214,6 +224,14 @@ See https://esbuild.github.io/api/#splitting for more details
See https://esbuild.github.io/api/#platform for more details
""",
),
"sourcemap": attr.string(
values = ["external", "inline", "both"],
mandatory = False,
doc = """Defines where sourcemaps are output and how they are included in the bundle. By default, a separate `.js.map` file is generated and referenced by the bundle. If 'external', a separate `.js.map` file is generated but not referenced by the bundle. If 'inline', a sourcemap is generated and its contents are inlined into the bundle (and no external sourcemap file is created). If 'both', a sourcemap is inlined and a `.js.map` file is created.

See https://esbuild.github.io/api/#sourcemap for more details
""",
),
"sources_content": attr.bool(
mandatory = False,
default = False,
Expand Down Expand Up @@ -270,9 +288,13 @@ def esbuild_macro(name, output_dir = False, **kwargs):
**kwargs
)
else:
output_map = None
sourcemap = kwargs.get("sourcemap", None)
if sourcemap != "inline":
output_map = "%s.js.map" % name
esbuild(
name = name,
output = "%s.js" % name,
output_map = "%s.js.map" % name,
output_map = output_map,
**kwargs
)
55 changes: 55 additions & 0 deletions packages/esbuild/test/sourcemap/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
load("//packages/esbuild/test:tests.bzl", "esbuild")
load("//packages/jasmine:index.bzl", "jasmine_node_test")
load("//packages/typescript:index.bzl", "ts_library")

ts_library(
name = "main",
srcs = [
"main.ts",
],
deps = [
"@npm//@types/node",
],
)

esbuild(
name = "bundle_default",
args = ["--keep-names"],
entry_point = "main.ts",
deps = [":main"],
)

esbuild(
name = "bundle_inline",
args = ["--keep-names"],
entry_point = "main.ts",
sourcemap = "inline",
deps = [":main"],
)

esbuild(
name = "bundle_external",
args = ["--keep-names"],
entry_point = "main.ts",
sourcemap = "external",
deps = [":main"],
)

esbuild(
name = "bundle_both",
args = ["--keep-names"],
entry_point = "main.ts",
sourcemap = "both",
deps = [":main"],
)

jasmine_node_test(
name = "bundle_test",
srcs = ["bundle_test.js"],
data = [
":bundle_both",
":bundle_default",
":bundle_external",
":bundle_inline",
],
)
62 changes: 62 additions & 0 deletions packages/esbuild/test/sourcemap/bundle_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const {readFileSync, exists} = require('fs');
const path = require('path');

const helper = require(process.env.BAZEL_NODE_RUNFILES_HELPER);
const locationBase = 'build_bazel_rules_nodejs/packages/esbuild/test/sourcemap/';

// Location for :bundle_default
const bundleDefaultLocation = helper.resolve(path.join(locationBase, 'bundle_default.js'));
const bundleDefaultSourcemapLocation =
helper.resolve(path.join(locationBase, 'bundle_default.js.map'));

// Location for :bundle_inline
const bundleInlineLocation = helper.resolve(path.join(locationBase, 'bundle_inline.js'));

// Location for :bundle_external
const bundleExternalLocation = helper.resolve(path.join(locationBase, 'bundle_external.js'));
const bundleExternalSourcemapLocation =
helper.resolve(path.join(locationBase, 'bundle_external.js.map'));

// Location for :bundle_both
const bundleBothLocation = helper.resolve(path.join(locationBase, 'bundle_both.js'));
const bundleBothSourcemapLocation = helper.resolve(path.join(locationBase, 'bundle_both.js.map'));

describe('esbuild sourcemap', () => {
it('creates an external sourcemap by default', () => {
const sourcemap = readFileSync(bundleDefaultSourcemapLocation, {encoding: 'utf8'});
expect(sourcemap).toContain(
'"sources": ["../../../../../../../packages/esbuild/test/sourcemap/main.ts"]');
});

it('does not inline the sourcemap by default', () => {
const bundle = readFileSync(bundleDefaultLocation, {encoding: 'utf8'});
expect(bundle).toContain('//# sourceMappingURL=bundle_default.js.map');
});

it('inlines the sourcemap when set to \'inline\'', () => {
const bundle = readFileSync(bundleInlineLocation, {encoding: 'utf8'});
expect(bundle).toContain('//# sourceMappingURL=data:application/json;base64');
});

it('has no sourcemap comment when set to \'external\'', () => {
const bundle = readFileSync(bundleExternalLocation, {encoding: 'utf8'});
expect(bundle).not.toContain('//# sourceMappingURL=');
});

it('creates an external sourcemap when set to \'external\'', () => {
const sourcemap = readFileSync(bundleExternalSourcemapLocation, {encoding: 'utf8'});
expect(sourcemap).toContain(
'"sources": ["../../../../../../../packages/esbuild/test/sourcemap/main.ts"]');
});

it('inlines the sourcemap when set to \'both\'', () => {
const bundle = readFileSync(bundleInlineLocation, {encoding: 'utf8'});
expect(bundle).toContain('//# sourceMappingURL=data:application/json;base64');
});

it('creates an external sourcemap when set to \'both\'', () => {
const sourcemap = readFileSync(bundleDefaultSourcemapLocation, {encoding: 'utf8'});
expect(sourcemap).toContain(
'"sources": ["../../../../../../../packages/esbuild/test/sourcemap/main.ts"]');
});
})
8 changes: 8 additions & 0 deletions packages/esbuild/test/sourcemap/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface Foo {
x: number, y: string,
}

export const foo: Foo = {
x: 123,
y: 'hello',
}