Skip to content

Commit

Permalink
feat(esbuild): add support for toolchains
Browse files Browse the repository at this point in the history
  • Loading branch information
mattem committed May 28, 2021
1 parent 8a44f62 commit b7c2be6
Show file tree
Hide file tree
Showing 26 changed files with 277 additions and 171 deletions.
4 changes: 2 additions & 2 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ browser_repositories(
)

# Setup esbuild dependencies
load("//packages/esbuild:esbuild_repo.bzl", "esbuild_dependencies")
load("//packages/esbuild:esbuild_repositories.bzl", "esbuild_repositories")

esbuild_dependencies()
esbuild_repositories()

#
# Dependencies to run stardoc & generating documentation
Expand Down
36 changes: 4 additions & 32 deletions examples/esbuild/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,14 @@ http_archive(
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/3.5.1/rules_nodejs-3.5.1.tar.gz"],
)

_ESBUILD_VERSION = "0.12.1"

http_archive(
name = "esbuild_darwin",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = "efb34692bfa34db61139eb8e46cd6cf767a42048f41c8108267279aaf58a948f",
strip_prefix = "package",
urls = [
"https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-%s.tgz" % _ESBUILD_VERSION,
],
)

http_archive(
name = "esbuild_windows",
build_file_content = """exports_files(["esbuild.exe"])""",
sha256 = "10439647b11c7fd1d9647fd98d022fe2188b4877d2d0b4acbe857f4e764b17a9",
strip_prefix = "package",
urls = [
"https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-%s.tgz" % _ESBUILD_VERSION,
],
)

http_archive(
name = "esbuild_linux",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = "de8409b90ec3c018ffd899b49ed5fc462c61b8c702ea0f9da013e0e1cd71549a",
strip_prefix = "package",
urls = [
"https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-%s.tgz" % _ESBUILD_VERSION,
],
)

load("@build_bazel_rules_nodejs//:index.bzl", "npm_install")

npm_install(
name = "npm",
package_json = "//:package.json",
package_lock_json = "//:package-lock.json",
)

load("@npm//@bazel/esbuild:esbuild_repositories.bzl", "esbuild_repositories")

esbuild_repositories()
5 changes: 0 additions & 5 deletions examples/esbuild/src/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ esbuild(
minify = True,
# setting node as the platform will default us to CJS
platform = "node",
tool = select({
"@bazel_tools//src/conditions:darwin": "@esbuild_darwin//:bin/esbuild",
"@bazel_tools//src/conditions:linux_x86_64": "@esbuild_linux//:bin/esbuild",
"@bazel_tools//src/conditions:windows": "@esbuild_windows//:esbuild.exe",
}),
deps = [
":lib",
],
Expand Down
24 changes: 17 additions & 7 deletions packages/esbuild/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ codeowners(

bzl_library(
name = "bzl",
srcs = glob(["**/*.bzl"]),
srcs = glob(["**/*.bzl"]) + [
"@bazel_tools//tools:bzl_srcs",
],
deps = [
"//packages/esbuild/toolchain:bzl",
"@bazel_skylib//lib:paths",
"@build_bazel_rules_nodejs//:bzl",
"@build_bazel_rules_nodejs//internal/common:bzl",
Expand All @@ -51,20 +54,27 @@ copy_file(
out = ":npm_version_check.js",
)

pkg_npm(
name = "npm_package",
filegroup(
name = "srcs",
srcs = [
"esbuild.bzl",
"esbuild_repositories.bzl",
"helpers.bzl",
"index.bzl",
"launcher.js",
"package.json",
],
build_file_content = """exports_files(["launcher.js"])
""",
)

pkg_npm(
name = "npm_package",
srcs = [
":srcs",
"//packages/esbuild/toolchain:srcs",
],
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",
"@build_bazel_rules_nodejs//packages/esbuild": "//@bazel/esbuild",
}),
deps = [
":README.md",
Expand Down
15 changes: 6 additions & 9 deletions packages/esbuild/esbuild.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ esbuild rule
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
load("@build_bazel_rules_nodejs//:providers.bzl", "ExternalNpmPackageInfo", "JSEcmaScriptModuleInfo", "JSModuleInfo", "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("@build_bazel_rules_nodejs//packages/esbuild/toolchain:toolchain.bzl", "TOOLCHAIN")
load(":helpers.bzl", "desugar_entry_point_names", "filter_files", "generate_path_mapping", "resolve_entry_point", "write_jsconfig_file")

def _esbuild_impl(ctx):
Expand Down Expand Up @@ -135,7 +136,7 @@ def _esbuild_impl(ctx):
execution_requirements = {"no-remote-exec": "1"}

launcher_args = ctx.actions.args()
launcher_args.add("--esbuild=%s" % ctx.executable.tool.path)
launcher_args.add("--esbuild=%s" % ctx.toolchains[TOOLCHAIN].binary.path)

run_node(
ctx = ctx,
Expand All @@ -148,7 +149,7 @@ def _esbuild_impl(ctx):
env = env,
executable = "launcher",
link_workspace_root = ctx.attr.link_workspace_root,
tools = [ctx.executable.tool],
tools = [ctx.toolchains[TOOLCHAIN].binary],
)

outputs_depset = depset(outputs)
Expand Down Expand Up @@ -307,15 +308,11 @@ edge16, node10, esnext). Default es2015.
See https://esbuild.github.io/api/#target for more details
""",
),
"tool": attr.label(
allow_single_file = True,
mandatory = True,
executable = True,
cfg = "exec",
doc = "An executable for the esbuild binary",
),
},
implementation = _esbuild_impl,
toolchains = [
str(TOOLCHAIN),
],
doc = """Runs the esbuild bundler under Bazel
For further information about esbuild, see https://esbuild.github.io/
Expand Down
42 changes: 0 additions & 42 deletions packages/esbuild/esbuild_repo.bzl

This file was deleted.

108 changes: 108 additions & 0 deletions packages/esbuild/esbuild_repositories.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""
Helper macro for fetching esbuild versions for internal tests and examples in rules_nodejs
"""

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@build_bazel_rules_nodejs//internal/common:check_version.bzl", "parse_version")

_VERSION = "0.12.1"
_MIN_VERSION = "0.12.0"
_MAX_VERSION = "0.13.0"

DARWIN_AMD64 = "darwin_amd64"
LINUX_AMD64 = "linux_amd64"
WINDOWS_AMD64 = "windows_amd64"

ESBUILD_SHAS = dict({
DARWIN_AMD64: "efb34692bfa34db61139eb8e46cd6cf767a42048f41c8108267279aaf58a948f",
LINUX_AMD64: "de8409b90ec3c018ffd899b49ed5fc462c61b8c702ea0f9da013e0e1cd71549a",
WINDOWS_AMD64: "10439647b11c7fd1d9647fd98d022fe2188b4877d2d0b4acbe857f4e764b17a9",
})

def _maybe(repo_rule, name, **kwargs):
if name not in native.existing_rules():
repo_rule(name = name, **kwargs)

def _esbuild_toolchain_repository_impl(repository_ctx):
content = "SUPPORTED_PLATFORMS = %s" % str(repository_ctx.attr.platforms)
repository_ctx.file("index.bzl", content = content)
repository_ctx.file("BUILD.bazel")

_esbuild_toolchain_repository = repository_rule(
implementation = _esbuild_toolchain_repository_impl,
attrs = {
"platforms": attr.string_list(
mandatory = True,
),
},
)

def esbuild_repositories(name = "esbuild_repositories", version = _VERSION, shas = ESBUILD_SHAS):
"""Helper for fetching and setting up the esbuild versions and toolchains
Args:
name: currently unused
version: version of esbuild to use
shas: mapping of platform_arch to the sha256 sum of the esbuild package for that platform
"""

current_version = parse_version(version)
if not (current_version >= parse_version(_MIN_VERSION) and current_version < parse_version(_MAX_VERSION)):
fail("Expected esbuild version to be >= %s and < %s, but got %s" % (_MIN_VERSION, _MAX_VERSION, version))

shas = dict({}, **shas)
platforms = []

if DARWIN_AMD64 in shas:
_maybe(
http_archive,
name = "esbuild_darwin_amd64",
urls = [
"https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-%s.tgz" % version,
],
strip_prefix = "package",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = shas.pop(DARWIN_AMD64),
)
platforms.append(DARWIN_AMD64)

if WINDOWS_AMD64 in shas:
_maybe(
http_archive,
name = "esbuild_windows_amd64",
urls = [
"https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-%s.tgz" % version,
],
strip_prefix = "package",
build_file_content = """exports_files(["esbuild.exe"])""",
sha256 = shas.pop(WINDOWS_AMD64),
)
platforms.append(WINDOWS_AMD64)

if LINUX_AMD64 in shas:
_maybe(
http_archive,
name = "esbuild_linux_amd64",
urls = [
"https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-%s.tgz" % version,
],
strip_prefix = "package",
build_file_content = """exports_files(["bin/esbuild"])""",
sha256 = shas.pop(LINUX_AMD64),
)
platforms.append(LINUX_AMD64)

if len(shas.keys()) > 0:
fail(
"Unsupported platforms defined for esbuild repositories: %s\n" % ", ".join(shas.keys()) +
"To define a custom esbuild toolchain, see the rules_nodejs esbuild documentation pages",
)

_esbuild_toolchain_repository(
name = "esbuild_toolchains",
platforms = platforms,
)

for platform in platforms:
toolchain_label = Label("@build_bazel_rules_nodejs//packages/esbuild/toolchain:esbuild_%s_toolchain" % platform)
native.register_toolchains("@%s//%s:%s" % (toolchain_label.workspace_name, toolchain_label.package, toolchain_label.name))
59 changes: 13 additions & 46 deletions packages/esbuild/index.docs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,57 +16,14 @@ or using yarn
yarn add -D @bazel/esbuild
```
Add an `http_archive` fetching the esbuild binary for each platform that you need to support.
The esbuild binary is fetched from npm automaticly and exposed via toolchains. Add the `esbuild_repositories` rule to the `WORKSPACE`:
```python
_ESBUILD_VERSION = "0.12.1" # 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 = "efb34692bfa34db61139eb8e46cd6cf767a42048f41c8108267279aaf58a948f",
)
http_archive(
name = "esbuild_windows",
urls = [
"https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-%s.tgz" % _ESBUILD_VERSION,
],
strip_prefix = "package",
build_file_content = \"""exports_files(["esbuild.exe"])\""",
sha256 = "10439647b11c7fd1d9647fd98d022fe2188b4877d2d0b4acbe857f4e764b17a9",
)
load("@npm//@bazel/esbuild:esbuild_repositories.bzl", "esbuild_repositories")
http_archive(
name = "esbuild_linux",
urls = [
"https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-%s.tgz" % _ESBUILD_VERSION,
],
strip_prefix = "package",
build_file_content = \"""exports_files(["bin/esbuild"])\""",
sha256 = "de8409b90ec3c018ffd899b49ed5fc462c61b8c702ea0f9da013e0e1cd71549a",
)
esbuild_repositories()
```
These can then be referenced on the `tool` attribute of the `esbuild` rule.
```python
esbuild(
name = "bundle",
...
tool = select({
"@bazel_tools//src/conditions:darwin": "@esbuild_darwin//:bin/esbuild",
"@bazel_tools//src/conditions:windows": "@esbuild_windows//:esbuild.exe",
"@bazel_tools//src/conditions:linux_x86_64": "@esbuild_linux//:bin/esbuild",
}),
)
```
It might be useful to wrap this locally in a macro for better reuseability, see `packages/esbuild/test/tests.bzl` for an example.
The `esbuild` rule can take a JS or TS dependency tree and bundle it to a single file, or split across multiple files, outputting a directory.
```python
Expand Down Expand Up @@ -116,8 +73,18 @@ load(
"@build_bazel_rules_nodejs//packages/esbuild:esbuild.bzl",
_esbuild = "esbuild",
)
load(
"@build_bazel_rules_nodejs//packages/esbuild:esbuild_repositories.bzl",
_esbuild_repositories = "esbuild_repositories",
)
load(
"@build_bazel_rules_nodejs//packages/esbuild/toolchain:toolchain.bzl",
_configure_esbuild_toolchain = "configure_esbuild_toolchain",
)

esbuild = _esbuild
esbuild_repositories = _esbuild_repositories
configure_esbuild_toolchain = _configure_esbuild_toolchain

# DO NOT ADD MORE rules here unless they appear in the generated docsite.
# Run yarn stardoc to re-generate the docsite.
Loading

0 comments on commit b7c2be6

Please sign in to comment.