From 5c5428298e6d023884371a956939462a96d4369c Mon Sep 17 00:00:00 2001 From: Matthew Soulanille Date: Sat, 13 Mar 2021 21:15:03 -0500 Subject: [PATCH 1/4] feat(esbuild): add 'sourcemap_inline' option to generate inline sourcemaps Inline sourcemaps are useful in debug servers and are easier to correctly set up than external sourcemaps. --- packages/esbuild/esbuild.bzl | 15 ++++++++++- .../esbuild/test/sourcemap_inline/BUILD.bazel | 27 +++++++++++++++++++ .../test/sourcemap_inline/bundle_test.js | 20 ++++++++++++++ .../esbuild/test/sourcemap_inline/main.ts | 8 ++++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 packages/esbuild/test/sourcemap_inline/BUILD.bazel create mode 100644 packages/esbuild/test/sourcemap_inline/bundle_test.js create mode 100644 packages/esbuild/test/sourcemap_inline/main.ts diff --git a/packages/esbuild/esbuild.bzl b/packages/esbuild/esbuild.bzl index f5d9aa5911..5f6495e090 100644 --- a/packages/esbuild/esbuild.bzl +++ b/packages/esbuild/esbuild.bzl @@ -54,8 +54,13 @@ def _esbuild_impl(ctx): args = ctx.actions.args() args.add("--bundle", entry_point.path) - args.add("--sourcemap") args.add("--preserve-symlinks") + + if ctx.attr.sourcemap_inline: + args.add_joined(["--sourcemap", "both"], join_with = "=") + else: + args.add("--sourcemap") + args.add_joined(["--platform", ctx.attr.platform], join_with = "=") args.add_joined(["--target", ctx.attr.target], join_with = "=") args.add_joined(["--log-level", "info"], join_with = "=") @@ -214,6 +219,14 @@ See https://esbuild.github.io/api/#splitting for more details See https://esbuild.github.io/api/#platform for more details """, ), + "sourcemap_inline": attr.bool( + mandatory = False, + default = False, + doc = """If True, esbuild inlines the sourcemap in the generated js file in addition to generating the external sourcemap. + +See '--sourcemap=both' at https://esbuild.github.io/api/#sourcemap for more details + """, + ), "sources_content": attr.bool( mandatory = False, default = False, diff --git a/packages/esbuild/test/sourcemap_inline/BUILD.bazel b/packages/esbuild/test/sourcemap_inline/BUILD.bazel new file mode 100644 index 0000000000..1be8d84d36 --- /dev/null +++ b/packages/esbuild/test/sourcemap_inline/BUILD.bazel @@ -0,0 +1,27 @@ +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", + args = ["--keep-names"], + entry_point = "main.ts", + sourcemap_inline = True, + deps = [":main"], +) + +jasmine_node_test( + name = "bundle_test", + srcs = ["bundle_test.js"], + data = [":bundle"], +) diff --git a/packages/esbuild/test/sourcemap_inline/bundle_test.js b/packages/esbuild/test/sourcemap_inline/bundle_test.js new file mode 100644 index 0000000000..6799197316 --- /dev/null +++ b/packages/esbuild/test/sourcemap_inline/bundle_test.js @@ -0,0 +1,20 @@ +const {readFileSync, exists} = require('fs'); + +const helper = require(process.env.BAZEL_NODE_RUNFILES_HELPER); +const location = + helper.resolve('build_bazel_rules_nodejs/packages/esbuild/test/sourcemap/bundle.js'); +const externalSourcemapLocation = + helper.resolve('build_bazel_rules_nodejs/packages/esbuild/test/sourcemap/bundle.js.map'); + +describe('esbuild sourcemap_inline', () => { + it('defines variables', () => { + const bundle = readFileSync(location, {encoding: 'utf8'}); + expect(bundle).toContain('//# sourceMappingURL=data:application/json;base64'); + }); + + it('still creates the external sourcemap', () => { + const externalSourcemap = readFileSync(externalSourcemapLocation, {encoding: 'utf8'}); + expect(externalSourcemap) + .toContain('"sources": ["../../../../../../../packages/esbuild/test/sourcemap/main.ts"]'); + }); +}) diff --git a/packages/esbuild/test/sourcemap_inline/main.ts b/packages/esbuild/test/sourcemap_inline/main.ts new file mode 100644 index 0000000000..7dabd31053 --- /dev/null +++ b/packages/esbuild/test/sourcemap_inline/main.ts @@ -0,0 +1,8 @@ +export interface Foo { + x: number, y: string, +} + +export const foo: Foo = { + x: 123, + y: 'hello', +} From 7040968ac94068d2bbf332d5113a98101a293c8a Mon Sep 17 00:00:00 2001 From: Matthew Soulanille Date: Sat, 13 Mar 2021 22:01:07 -0500 Subject: [PATCH 2/4] fix(esbuild): fix an incorrect test name --- packages/esbuild/test/sourcemap_inline/bundle_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/esbuild/test/sourcemap_inline/bundle_test.js b/packages/esbuild/test/sourcemap_inline/bundle_test.js index 6799197316..b8fea5c681 100644 --- a/packages/esbuild/test/sourcemap_inline/bundle_test.js +++ b/packages/esbuild/test/sourcemap_inline/bundle_test.js @@ -7,7 +7,7 @@ const externalSourcemapLocation = helper.resolve('build_bazel_rules_nodejs/packages/esbuild/test/sourcemap/bundle.js.map'); describe('esbuild sourcemap_inline', () => { - it('defines variables', () => { + it('inlines the sourcemap', () => { const bundle = readFileSync(location, {encoding: 'utf8'}); expect(bundle).toContain('//# sourceMappingURL=data:application/json;base64'); }); From e7d9614e65335eea42c390640c81cf20ba1c23f8 Mon Sep 17 00:00:00 2001 From: Matthew Soulanille Date: Sat, 13 Mar 2021 22:17:13 -0500 Subject: [PATCH 3/4] fix(esbuild): fix incorrect test paths --- packages/esbuild/test/sourcemap_inline/bundle_test.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/esbuild/test/sourcemap_inline/bundle_test.js b/packages/esbuild/test/sourcemap_inline/bundle_test.js index b8fea5c681..d26c19e79e 100644 --- a/packages/esbuild/test/sourcemap_inline/bundle_test.js +++ b/packages/esbuild/test/sourcemap_inline/bundle_test.js @@ -2,9 +2,9 @@ const {readFileSync, exists} = require('fs'); const helper = require(process.env.BAZEL_NODE_RUNFILES_HELPER); const location = - helper.resolve('build_bazel_rules_nodejs/packages/esbuild/test/sourcemap/bundle.js'); + helper.resolve('build_bazel_rules_nodejs/packages/esbuild/test/sourcemap_inline/bundle.js'); const externalSourcemapLocation = - helper.resolve('build_bazel_rules_nodejs/packages/esbuild/test/sourcemap/bundle.js.map'); + helper.resolve('build_bazel_rules_nodejs/packages/esbuild/test/sourcemap_inline/bundle.js.map'); describe('esbuild sourcemap_inline', () => { it('inlines the sourcemap', () => { @@ -15,6 +15,7 @@ describe('esbuild sourcemap_inline', () => { it('still creates the external sourcemap', () => { const externalSourcemap = readFileSync(externalSourcemapLocation, {encoding: 'utf8'}); expect(externalSourcemap) - .toContain('"sources": ["../../../../../../../packages/esbuild/test/sourcemap/main.ts"]'); + .toContain( + '"sources": ["../../../../../../../packages/esbuild/test/sourcemap_inline/main.ts"]'); }); }) From 70118067387df46a1fbb4abcd7bf702813147b6a Mon Sep 17 00:00:00 2001 From: Matthew Soulanille Date: Wed, 17 Mar 2021 20:26:52 -0400 Subject: [PATCH 4/4] feat(esbuild): add 'sourcemap' and remove 'sourcemap_inline' --- packages/esbuild/esbuild.bzl | 27 +++++--- packages/esbuild/test/sourcemap/BUILD.bazel | 55 ++++++++++++++++ .../esbuild/test/sourcemap/bundle_test.js | 62 +++++++++++++++++++ .../{sourcemap_inline => sourcemap}/main.ts | 0 .../esbuild/test/sourcemap_inline/BUILD.bazel | 27 -------- .../test/sourcemap_inline/bundle_test.js | 21 ------- 6 files changed, 135 insertions(+), 57 deletions(-) create mode 100644 packages/esbuild/test/sourcemap/BUILD.bazel create mode 100644 packages/esbuild/test/sourcemap/bundle_test.js rename packages/esbuild/test/{sourcemap_inline => sourcemap}/main.ts (100%) delete mode 100644 packages/esbuild/test/sourcemap_inline/BUILD.bazel delete mode 100644 packages/esbuild/test/sourcemap_inline/bundle_test.js diff --git a/packages/esbuild/esbuild.bzl b/packages/esbuild/esbuild.bzl index 5f6495e090..461c38f3a7 100644 --- a/packages/esbuild/esbuild.bzl +++ b/packages/esbuild/esbuild.bzl @@ -54,13 +54,13 @@ def _esbuild_impl(ctx): args = ctx.actions.args() args.add("--bundle", entry_point.path) - args.add("--preserve-symlinks") - if ctx.attr.sourcemap_inline: - args.add_joined(["--sourcemap", "both"], join_with = "=") + 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 = "=") args.add_joined(["--log-level", "info"], join_with = "=") @@ -92,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 = "=") @@ -219,12 +224,12 @@ See https://esbuild.github.io/api/#splitting for more details See https://esbuild.github.io/api/#platform for more details """, ), - "sourcemap_inline": attr.bool( + "sourcemap": attr.string( + values = ["external", "inline", "both"], mandatory = False, - default = False, - doc = """If True, esbuild inlines the sourcemap in the generated js file in addition to generating the external sourcemap. + 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 '--sourcemap=both' at https://esbuild.github.io/api/#sourcemap for more details +See https://esbuild.github.io/api/#sourcemap for more details """, ), "sources_content": attr.bool( @@ -283,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 ) diff --git a/packages/esbuild/test/sourcemap/BUILD.bazel b/packages/esbuild/test/sourcemap/BUILD.bazel new file mode 100644 index 0000000000..7138fc8f27 --- /dev/null +++ b/packages/esbuild/test/sourcemap/BUILD.bazel @@ -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", + ], +) diff --git a/packages/esbuild/test/sourcemap/bundle_test.js b/packages/esbuild/test/sourcemap/bundle_test.js new file mode 100644 index 0000000000..dd7ef34d5a --- /dev/null +++ b/packages/esbuild/test/sourcemap/bundle_test.js @@ -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"]'); + }); +}) diff --git a/packages/esbuild/test/sourcemap_inline/main.ts b/packages/esbuild/test/sourcemap/main.ts similarity index 100% rename from packages/esbuild/test/sourcemap_inline/main.ts rename to packages/esbuild/test/sourcemap/main.ts diff --git a/packages/esbuild/test/sourcemap_inline/BUILD.bazel b/packages/esbuild/test/sourcemap_inline/BUILD.bazel deleted file mode 100644 index 1be8d84d36..0000000000 --- a/packages/esbuild/test/sourcemap_inline/BUILD.bazel +++ /dev/null @@ -1,27 +0,0 @@ -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", - args = ["--keep-names"], - entry_point = "main.ts", - sourcemap_inline = True, - deps = [":main"], -) - -jasmine_node_test( - name = "bundle_test", - srcs = ["bundle_test.js"], - data = [":bundle"], -) diff --git a/packages/esbuild/test/sourcemap_inline/bundle_test.js b/packages/esbuild/test/sourcemap_inline/bundle_test.js deleted file mode 100644 index d26c19e79e..0000000000 --- a/packages/esbuild/test/sourcemap_inline/bundle_test.js +++ /dev/null @@ -1,21 +0,0 @@ -const {readFileSync, exists} = require('fs'); - -const helper = require(process.env.BAZEL_NODE_RUNFILES_HELPER); -const location = - helper.resolve('build_bazel_rules_nodejs/packages/esbuild/test/sourcemap_inline/bundle.js'); -const externalSourcemapLocation = - helper.resolve('build_bazel_rules_nodejs/packages/esbuild/test/sourcemap_inline/bundle.js.map'); - -describe('esbuild sourcemap_inline', () => { - it('inlines the sourcemap', () => { - const bundle = readFileSync(location, {encoding: 'utf8'}); - expect(bundle).toContain('//# sourceMappingURL=data:application/json;base64'); - }); - - it('still creates the external sourcemap', () => { - const externalSourcemap = readFileSync(externalSourcemapLocation, {encoding: 'utf8'}); - expect(externalSourcemap) - .toContain( - '"sources": ["../../../../../../../packages/esbuild/test/sourcemap_inline/main.ts"]'); - }); -})