Skip to content

Commit

Permalink
feat(bazel/spec-bundling): generate ESM mjs bundle for node spec bundles
Browse files Browse the repository at this point in the history
  • Loading branch information
devversion committed Jun 15, 2022
1 parent 375f027 commit 358e09d
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 32 deletions.
28 changes: 28 additions & 0 deletions bazel/esbuild/index.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,33 @@ def esbuild(
**kwargs
)

def esbuild_esm_bundle(name, **kwargs):
"""ESBuild macro supports an ESM/CJS interop.
Args:
name: Name of the target
**kwargs: Other arguments passed to the `esbuild` rule.
"""

args = dict(
resolveExtensions = [".mjs", ".js"],
outExtension = {".js": ".mjs"},
# Workaround for: https://github.com/evanw/esbuild/issues/1921.
banner = {
"js": """
import {createRequire as __cjsCompatRequire} from 'module';
const require = __cjsCompatRequire(import.meta.url);
""",
},
)

esbuild(
name = name,
format = "esm",
args = args,
**kwargs
)

def esbuild_amd(name, entry_point, module_name, testonly = False, config = None, deps = [], **kwargs):
"""Generates an AMD bundle for the specified entry-point with the given AMD module name."""
expand_template(
Expand Down Expand Up @@ -47,6 +74,7 @@ def esbuild_amd(name, entry_point, module_name, testonly = False, config = None,
testonly = testonly,
deps = deps,
entry_point = entry_point,
format = "iife",
config = "%s_config_lib" % name,
**kwargs
)
3 changes: 0 additions & 3 deletions bazel/spec-bundling/esbuild.config-tmpl.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,5 @@ export default {
conditions: ['es2020', 'es2015', 'module'],
// This ensures that we prioritize ES2020. RxJS would otherwise use the ESM5 output.
mainFields: ['es2020', 'es2015', 'module', 'main'],
// Use the `iife` format for the test entry-point as tests should run immediately.
// For browser tests which are wrapped in an AMD header and footer, this works as well.
format: 'iife',
plugins,
};
6 changes: 3 additions & 3 deletions bazel/spec-bundling/index.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//bazel/esbuild:index.bzl", "esbuild", "esbuild_amd", "esbuild_config")
load("//bazel/esbuild:index.bzl", "esbuild_amd", "esbuild_config", "esbuild_esm_bundle")
load("//bazel/spec-bundling:spec-entrypoint.bzl", "spec_entrypoint")
load("//bazel/spec-bundling:bundle-config.bzl", "spec_bundle_config_file")

Expand Down Expand Up @@ -63,16 +63,16 @@ def spec_bundle(

# Browser tests (Karma) need named AMD modules to load.
# TODO(devversion): consider updating `@bazel/concatjs` to support loading JS files directly.
esbuild_rule = esbuild_amd if is_browser_test else esbuild
esbuild_rule = esbuild_amd if is_browser_test else esbuild_esm_bundle
amd_name = "%s/%s/%s" % (workspace_name, package_name, name + "_spec") if is_browser_test else None

esbuild_rule(
name = "%s_bundle" % name,
testonly = True,
config = ":%s_config" % name,
output = "%s_spec.%s" % (name, "js" if is_browser_test else "mjs"),
entry_point = ":%s_spec_entrypoint" % name,
module_name = amd_name,
output = "%s_spec.js" % name,
target = target,
platform = platform,
deps = deps + [":%s_spec_entrypoint" % name],
Expand Down
3 changes: 3 additions & 0 deletions ng-dev/utils/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ ts_library(

jasmine_node_test(
name = "test",
data = ["@npm//@yarnpkg/lockfile"],
# Same reasoning as in "ng-dev/BUILD.bazel". This package cannot be bundled.
external = ["@yarnpkg/lockfile"],
specs = [":test_lib"],
)
47 changes: 21 additions & 26 deletions tools/esbuild.bzl
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
load("//bazel/esbuild:index.bzl", _esbuild = "esbuild", _esbuild_config = "esbuild_config")
load(
"//bazel/esbuild:index.bzl",
_esbuild = "esbuild",
_esbuild_config = "esbuild_config",
_esbuild_esm_bundle = "esbuild_esm_bundle",
)
load("//bazel:extract_js_module_output.bzl", "extract_js_module_output")
load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test")

esbuild_config = _esbuild_config

def esbuild(name, platform = "node", target = "node14", deps = [], **kwargs):
def _esbuild_devmode_prioritize(
esbuild_rule,
name,
platform = "node",
target = "node14",
deps = [],
**kwargs):
# TODO: Rename once devmode and prodmode have been combined.
# This helps speeding up building as ESBuild (used internally by the rule) would
# request both devmode and prodmode output flavor (resulting in 2x TS compilations).
Expand All @@ -19,39 +30,23 @@ def esbuild(name, platform = "node", target = "node14", deps = [], **kwargs):
include_declarations = False,
)

_esbuild(
esbuild_rule(
name = name,
platform = platform,
target = target,
deps = [":%s_devmode_deps" % name],
**kwargs
)

def esbuild_esm_bundle(name, **kwargs):
"""ESBuild macro that prioritizes ESM output and supports an ESM/CJS interop.
Args:
name: Name of the target
deps: List of dependencies
**kwargs: Other arguments passed to the `esbuild` rule.
"""

args = dict(
resolveExtensions = [".mjs", ".js"],
outExtension = {".js": ".mjs"},
# Workaround for: https://github.com/evanw/esbuild/issues/1921.
banner = {
"js": """
import {createRequire as __cjsCompatRequire} from 'module';
const require = __cjsCompatRequire(import.meta.url);
""",
},
def esbuild(**kwargs):
_esbuild_devmode_prioritize(
_esbuild,
**kwargs
)

esbuild(
name = name,
format = "esm",
args = args,
def esbuild_esm_bundle(**kwargs):
_esbuild_devmode_prioritize(
_esbuild_esm_bundle,
**kwargs
)

Expand Down

0 comments on commit 358e09d

Please sign in to comment.