Skip to content

Commit

Permalink
fix(esbuild): use run_node to invoke linker before running esuild
Browse files Browse the repository at this point in the history
  • Loading branch information
mattem authored and alexeagle committed Apr 12, 2021
1 parent 1c50e96 commit be184c2
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 29 deletions.
8 changes: 4 additions & 4 deletions examples/esbuild/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ http_archive(
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/3.3.0/rules_nodejs-3.3.0.tar.gz"],
)

_ESBUILD_VERSION = "0.11.5"
_ESBUILD_VERSION = "0.11.6"

http_archive(
name = "esbuild_darwin",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = "98436890727bdb0d4beddd9c9e07d0aeff0e8dfe0169f85e568eca0dd43f665e",
sha256 = "2b06365b075b854654fc9ed26fcd48a0c38947e1c8d5151ce400cd1e173bb138",
strip_prefix = "package",
urls = [
"https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-%s.tgz" % _ESBUILD_VERSION,
Expand All @@ -40,7 +40,7 @@ http_archive(
http_archive(
name = "esbuild_windows",
build_file_content = """exports_files(["esbuild.exe"])""",
sha256 = "589c8ff97210bd41de106e6317ce88f9e88d2cacfd8178ae1217f2b857ff6c3a",
sha256 = "ddab1121833f0a12ca4fb3e288231e058f5526310671e84c0a9aa575340bb20b",
strip_prefix = "package",
urls = [
"https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-%s.tgz" % _ESBUILD_VERSION,
Expand All @@ -50,7 +50,7 @@ http_archive(
http_archive(
name = "esbuild_linux",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = "113c2e84895f4422a3676db4e15d9f01b2b4fac041edab25284fdb9574ba58a0",
sha256 = "34612e3e15e6c31d9d742d3fd677bd5208b7e5c0ee9c93809999138c6c5c1039",
strip_prefix = "package",
urls = [
"https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-%s.tgz" % _ESBUILD_VERSION,
Expand Down
7 changes: 6 additions & 1 deletion packages/esbuild/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ load("//third_party/github.com/bazelbuild/bazel-skylib:rules/copy_file.bzl", "co

package(default_visibility = ["//visibility:public"])

exports_files(["launcher.js"])

codeowners(
teams = ["@mattem"],
)
Expand Down Expand Up @@ -67,11 +69,14 @@ pkg_npm(
"esbuild.bzl",
"helpers.bzl",
"index.bzl",
"launcher.js",
"package.json",
],
build_file_content = " ",
build_file_content = """exports_files(["launcher.js"])
""",
substitutions = dict({
"@build_bazel_rules_nodejs//packages/esbuild:esbuild.bzl": "//@bazel/esbuild:esbuild.bzl",
"@build_bazel_rules_nodejs//packages/esbuild:launcher.js": "//@bazel/esbuild:launcher.js",
}),
deps = [
":npm_version_check",
Expand Down
8 changes: 4 additions & 4 deletions packages/esbuild/_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ yarn add -D @bazel/esbuild
Add an `http_archive` fetching the esbuild binary for each platform that you need to support.

```python
_ESBUILD_VERSION = "0.11.5" # reminder: update SHAs below when changing this value
_ESBUILD_VERSION = "0.11.6" # reminder: update SHAs below when changing this value
http_archive(
name = "esbuild_darwin",
urls = [
"https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-%s.tgz" % _ESBUILD_VERSION,
],
strip_prefix = "package",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = "98436890727bdb0d4beddd9c9e07d0aeff0e8dfe0169f85e568eca0dd43f665e",
sha256 = "2b06365b075b854654fc9ed26fcd48a0c38947e1c8d5151ce400cd1e173bb138",
)

http_archive(
Expand All @@ -36,7 +36,7 @@ http_archive(
],
strip_prefix = "package",
build_file_content = """exports_files(["esbuild.exe"])""",
sha256 = "589c8ff97210bd41de106e6317ce88f9e88d2cacfd8178ae1217f2b857ff6c3a",
sha256 = "ddab1121833f0a12ca4fb3e288231e058f5526310671e84c0a9aa575340bb20b",
)

http_archive(
Expand All @@ -46,7 +46,7 @@ http_archive(
],
strip_prefix = "package",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = "113c2e84895f4422a3676db4e15d9f01b2b4fac041edab25284fdb9574ba58a0",
sha256 = "34612e3e15e6c31d9d742d3fd677bd5208b7e5c0ee9c93809999138c6c5c1039",
)
```

Expand Down
44 changes: 28 additions & 16 deletions packages/esbuild/esbuild.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
esbuild rule
"""

load("@build_bazel_rules_nodejs//:providers.bzl", "JSEcmaScriptModuleInfo", "JSModuleInfo", "NpmPackageInfo", "node_modules_aspect")
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
load("@build_bazel_rules_nodejs//:providers.bzl", "JSEcmaScriptModuleInfo", "JSModuleInfo", "NpmPackageInfo", "node_modules_aspect", "run_node")
load("@build_bazel_rules_nodejs//internal/linker:link_node_modules.bzl", "MODULE_MAPPINGS_ASPECT_RESULTS_NAME", "module_mappings_aspect")
load(":helpers.bzl", "filter_files", "generate_path_mapping", "resolve_entry_point", "write_jsconfig_file")

Expand All @@ -14,10 +15,6 @@ def _esbuild_impl(ctx):
# Path alias mapings are used to create a jsconfig with mappings so that esbuild
# how to resolve custom package or module names
path_alias_mappings = dict()
npm_workspaces = []

if (ctx.attr.link_workspace_root):
path_alias_mappings.update(generate_path_mapping(ctx.workspace_name, "."))

for dep in ctx.attr.deps:
if JSEcmaScriptModuleInfo in dep:
Expand All @@ -33,19 +30,12 @@ def _esbuild_impl(ctx):

if NpmPackageInfo in dep:
deps_depsets.append(dep[NpmPackageInfo].sources)
npm_workspaces.append(dep[NpmPackageInfo].workspace)

# Collect the path alias mapping to resolve packages correctly
if hasattr(dep, MODULE_MAPPINGS_ASPECT_RESULTS_NAME):
for key, value in getattr(dep, MODULE_MAPPINGS_ASPECT_RESULTS_NAME).items():
path_alias_mappings.update(generate_path_mapping(key, value[1].replace(ctx.bin_dir.path + "/", "")))

node_modules_mappings = [
"../../../external/%s/node_modules/*" % workspace
for workspace in depset(npm_workspaces).to_list()
]
path_alias_mappings.update({"*": node_modules_mappings})

deps_inputs = depset(transitive = deps_depsets).to_list()
inputs = filter_files(ctx.files.entry_point) + ctx.files.srcs + deps_inputs

Expand All @@ -55,6 +45,7 @@ def _esbuild_impl(ctx):
entry_point = resolve_entry_point(ctx.file.entry_point, inputs, ctx.files.srcs)

args = ctx.actions.args()
args.use_param_file(param_file_arg = "--esbuild_flags=%s", use_always = True)

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

Expand Down Expand Up @@ -125,19 +116,25 @@ def _esbuild_impl(ctx):
if "no-remote-exec" in ctx.attr.tags:
execution_requirements = {"no-remote-exec": "1"}

ctx.actions.run(
launcher_args = ctx.actions.args()
launcher_args.add("--esbuild=%s" % ctx.executable.tool.path)

run_node(
ctx = ctx,
inputs = depset(inputs),
outputs = outputs,
executable = ctx.executable.tool,
arguments = [args],
arguments = [launcher_args, args],
progress_message = "%s Javascript %s [esbuild]" % ("Bundling" if not ctx.attr.output_dir else "Splitting", entry_point.short_path),
execution_requirements = execution_requirements,
mnemonic = "esbuild",
env = env,
executable = "launcher",
link_workspace_root = ctx.attr.link_workspace_root,
tools = [ctx.executable.tool],
)

return [
DefaultInfo(files = depset(outputs + [jsconfig_file])),
DefaultInfo(files = depset(outputs)),
]

esbuild = rule(
Expand Down Expand Up @@ -189,6 +186,12 @@ and cjs when platform is node. If performing code splitting, defaults to esm.
See https://esbuild.github.io/api/#format for more details
""",
),
"launcher": attr.label(
mandatory = True,
executable = True,
doc = "Internal use only",
cfg = "exec",
),
"link_workspace_root": attr.bool(
doc = """Link the workspace root to the bin_dir to support absolute requires like 'my_wksp/path/to/file'.
If source files need to be required then they can be copied to the bin_dir with copy_to_bin.""",
Expand Down Expand Up @@ -296,10 +299,18 @@ def esbuild_macro(name, output_dir = False, **kwargs):
**kwargs: All other args from `esbuild_bundle`
"""

kwargs.pop("launcher", None)
_launcher = "_%s_esbuild_launcher" % name
nodejs_binary(
name = _launcher,
entry_point = Label("@build_bazel_rules_nodejs//packages/esbuild:launcher.js"),
)

if output_dir == True:
esbuild(
name = name,
output_dir = True,
launcher = _launcher,
**kwargs
)
else:
Expand All @@ -316,5 +327,6 @@ def esbuild_macro(name, output_dir = False, **kwargs):
name = name,
output = output,
output_map = output_map,
launcher = _launcher,
**kwargs
)
8 changes: 4 additions & 4 deletions packages/esbuild/esbuild_repo.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Helper macro for fetching esbuild versions for internal tests and examples in ru

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

_VERSION = "0.11.5"
_VERSION = "0.11.6"

def esbuild_dependencies():
"""Helper to install required dependencies for the esbuild rules"""
Expand All @@ -20,7 +20,7 @@ def esbuild_dependencies():
],
strip_prefix = "package",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = "98436890727bdb0d4beddd9c9e07d0aeff0e8dfe0169f85e568eca0dd43f665e",
sha256 = "2b06365b075b854654fc9ed26fcd48a0c38947e1c8d5151ce400cd1e173bb138",
)
http_archive(
name = "esbuild_windows",
Expand All @@ -29,7 +29,7 @@ def esbuild_dependencies():
],
strip_prefix = "package",
build_file_content = """exports_files(["esbuild.exe"])""",
sha256 = "589c8ff97210bd41de106e6317ce88f9e88d2cacfd8178ae1217f2b857ff6c3a",
sha256 = "ddab1121833f0a12ca4fb3e288231e058f5526310671e84c0a9aa575340bb20b",
)
http_archive(
name = "esbuild_linux",
Expand All @@ -38,5 +38,5 @@ def esbuild_dependencies():
],
strip_prefix = "package",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = "113c2e84895f4422a3676db4e15d9f01b2b4fac041edab25284fdb9574ba58a0",
sha256 = "34612e3e15e6c31d9d742d3fd677bd5208b7e5c0ee9c93809999138c6c5c1039",
)
25 changes: 25 additions & 0 deletions packages/esbuild/launcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const {spawn} = require('child_process');
const {readFileSync} = require('fs');

function getFlag(flag, required = true) {
const argvFlag = process.argv.find(arg => arg.startsWith(`${flag}=`));
if (required && !argvFlag) {
console.error(`Expected flag '${flag}' passed to launcher, but not found`);
process.exit(1);
}

return argvFlag.split('=')[1];
}

const esbuild = getFlag('--esbuild');
const params_file_path = getFlag('--esbuild_flags');

let flags = [];
try {
flags = readFileSync(params_file_path, {encoding: 'utf8'}).trim().replace(/'/gm, '').split('\n');
} catch (e) {
console.error('Error while reading esbuild flags param file', e);
process.exit(1);
}

spawn(esbuild, flags, {detached: true, stdio: 'inherit'});
3 changes: 3 additions & 0 deletions packages/esbuild/test/vanilla_js/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ esbuild(
"name.js",
],
entry_point = "main.js",
deps = [
"@npm//date-fns",
],
)

nodejs_binary(
Expand Down
3 changes: 3 additions & 0 deletions packages/esbuild/test/vanilla_js/main.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
const NAME = require('./name').NAME;
const {isDate} = require('date-fns');

console.log(isDate(NAME));
console.log(NAME);
1 change: 1 addition & 0 deletions packages/esbuild/test/vanilla_js/output.golden.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
false
rules_nodejs

0 comments on commit be184c2

Please sign in to comment.