diff --git a/BUILD.bazel b/BUILD.bazel
index d91967171..c9f199d10 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -11,7 +11,7 @@ link_all_npm_packages(name = "node_modules")
# Link the acorn package, which was fetched separately with npm_import from /WORKSPACE, to the
# virtual store in bazel-bin/node_modules/.aspect_rules_js
link_acorn(
- name = "link_acorn",
+ name = "node_modules/acorn",
# `direct` set to False as an example of *not* also linking this 3rd dependency as a
# direct dependency in the package at bazel-bin/node_modules/@mycorp/mylib. Alternately,
# you may specify link_packages in the npm_import of this package and direct is then
@@ -21,7 +21,7 @@ link_acorn(
# Linking a first-party dependency to the virtual store in bazel-bin/node_modules/.aspect_rules_js
link_npm_package(
- name = "link_mycorp_mylib",
+ name = "node_modules/@mycorp/mylib",
src = "//examples/lib",
# `direct` set to False as an example of *not* also linking this first-party dependency as a
# direct dependency in the package at bazel-bin/node_modules/@mycorp/mylib.
diff --git a/docs/link_npm_package.md b/docs/link_npm_package.md
index 2b6ae9e17..f87f310d5 100644
--- a/docs/link_npm_package.md
+++ b/docs/link_npm_package.md
@@ -81,10 +81,10 @@ link_npm_package(name, 1:
+ package_scope = _import.package.split("/", 1)[0]
+ if package_scope not in package_scopes:
+ package_scopes.append(package_scope)
+ for fp_link in fp_links.values():
+ fp_package = fp_link.get("package")
+ if len(fp_package.split("/", 1)) > 1:
+ package_scope = fp_package.split("/", 1)[0]
+ if package_scope not in package_scopes:
+ package_scopes.append(package_scope)
+ for package_scope in package_scopes:
+ defs_bzl_body.append(""" scoped_direct_targets["{}"] = []""".format(package_scope))
+
+ for (i, _import) in enumerate(npm_imports):
maybe_deps = ("""
deps = %s,""" % starlark_codegen_utils.to_dict_attr(_import.deps, 2)) if len(_import.deps) > 0 else ""
maybe_transitive_closure = ("""
@@ -443,33 +467,25 @@ def _impl(rctx):
links_suffix = utils.links_suffix,
),
)
- defs_bzl_body.append(""" direct_targets.append(link_{i}(name = "{direct_link_prefix}{bazel_name}", direct = None, fail_if_no_link = False))""".format(
+ defs_bzl_body.append(""" direct_targets.append(link_{i}(name = "{{}}/{name}".format(name), direct = None, fail_if_no_link = False))""".format(
i = i,
- direct_link_prefix = utils.direct_link_prefix,
- bazel_name = utils.bazel_name(_import.package),
+ name = _import.package,
))
+ if len(_import.package.split("/", 1)) > 1:
+ package_scope = _import.package.split("/", 1)[0]
+ defs_bzl_body.append(""" scoped_direct_targets["{package_scope}"].append(direct_targets[-1])""".format(
+ package_scope = package_scope,
+ ))
- # For direct dependencies create alias targets @repo_name//name, @repo_name//@scope/name,
- # @repo_name//name:dir and @repo_name//@scope/name:dir
for link_package in _import.link_packages:
- build_file_path = paths.normalize(paths.join(link_package, _import.package, "BUILD.bazel"))
- rctx.file(build_file_path, "\n".join(generated_by_lines + [
- _ALIAS_TMPL.format(
- basename = paths.basename(_import.package),
- bazel_name = utils.bazel_name(_import.package),
- dir_suffix = utils.dir_suffix,
- direct_link_prefix = utils.direct_link_prefix,
- link_package = link_package,
- link_workspace = rctx.attr.pnpm_lock.workspace_name,
- ),
- ]))
-
# Generate a package_json.bzl file for the bin entries (even if there are none)
# Note, there's no has_bin attribute on npm_import so we can't get the boolean
# value from the _import struct.
# If this is a problem, we could lookup into the packages again like
# if lockfile.get("packages").values()[i].get("hasBin"):
if True:
+ build_file_path = paths.normalize(paths.join(link_package, _import.package, "BUILD.bazel"))
+ rctx.file(build_file_path, "\n".join(generated_by_lines))
package_json_bzl_file_path = paths.normalize(paths.join(link_package, _import.package, _PACKAGE_JSON_BZL_FILENAME))
repo_package_json_bzl = paths.normalize(paths.join(link_package, _PACKAGE_JSON_BZL_FILENAME)).rsplit("/", 1)
if len(repo_package_json_bzl) == 1:
@@ -483,64 +499,6 @@ def _impl(rctx):
),
]))
- # Gather scoped packages
- if len(_import.package.split("/", 1)) > 1:
- package_scope = _import.package.split("/", 1)[0]
- build_file_package = paths.normalize(paths.join(link_package, package_scope))
- if build_file_package not in scoped_packages:
- scoped_packages[build_file_package] = []
- scoped_packages[build_file_package].append(
- "@{link_workspace}//{link_package}:{direct_link_prefix}{bazel_name}".format(
- bazel_name = utils.bazel_name(_import.package),
- direct_link_prefix = utils.direct_link_prefix,
- link_package = link_package,
- link_workspace = rctx.attr.pnpm_lock.workspace_name,
- ),
- )
-
- fp_links = {}
-
- # Look for first-party links
- for import_path, importer in importers.items():
- dependencies = importer.get("dependencies")
- if type(dependencies) != "dict":
- fail("expected dict of dependencies in processed importer '%s'" % import_path)
- link_package = _link_package(root_package, import_path)
- for dep_package, dep_version in dependencies.items():
- if dep_version.startswith("link:"):
- dep_importer = paths.normalize(paths.join(import_path, dep_version[len("link:"):]))
- dep_path = _link_package(root_package, import_path, dep_version[len("link:"):])
- dep_key = "{}+{}".format(dep_package, dep_path)
- if dep_key in fp_links.keys():
- fp_links[dep_key]["link_packages"].append(link_package)
- else:
- transitive_deps = []
- raw_deps = {}
- if dep_importer in importers.keys():
- raw_deps = importers.get(dep_importer).get("dependencies")
- for raw_package, raw_version in raw_deps.items():
- if raw_version.startswith("link:"):
- raw_path = _link_package(root_package, dep_importer, raw_version[len("link:"):])
- raw_bazel_name = utils.bazel_name(raw_package, raw_path)
- else:
- raw_bazel_name = utils.bazel_name(raw_package, raw_version)
- transitive_deps.append("//{root_package}:{store_link_prefix}{bazel_name}".format(
- bazel_name = raw_bazel_name,
- root_package = root_package,
- store_link_prefix = utils.store_link_prefix,
- ))
- fp_links[dep_key] = {
- "package": dep_package,
- "path": dep_path,
- "link_packages": [link_package],
- "deps": transitive_deps,
- }
-
- if fp_links:
- defs_bzl_header.append("""load("@aspect_rules_js//npm/private:link_npm_package.bzl",
- _link_npm_package_store = "link_npm_package_store",
- _link_npm_package_direct = "link_npm_package_direct")""")
-
for fp_link in fp_links.values():
fp_package = fp_link.get("package")
fp_path = fp_link.get("path")
@@ -552,17 +510,15 @@ def _impl(rctx):
defs_bzl_body.append(_FP_STORE_TMPL.format(
bazel_name = fp_bazel_name,
deps = starlark_codegen_utils.to_list_attr(fp_deps, 3),
- direct_link_prefix = utils.direct_link_prefix,
npm_package_target = fp_target,
package = fp_package,
store_link_prefix = utils.store_link_prefix,
))
defs_bzl_body.append(_FP_DIRECT_TMPL.format(
- alias = utils.bazel_name(fp_package),
bazel_name = fp_bazel_name,
+ name = fp_package,
dir_suffix = utils.dir_suffix,
- direct_link_prefix = utils.direct_link_prefix,
link_packages = fp_link_packages,
package = fp_package,
package_directory_output_group = utils.package_directory_output_group,
@@ -570,38 +526,22 @@ def _impl(rctx):
store_link_prefix = utils.store_link_prefix,
))
- # Create alias targets @repo_name//name, @repo_name//@scope/name,
- # @repo_name//name:dir and @repo_name//@scope/name:dir
- for link_package in fp_link_packages:
- build_file_path = paths.normalize(paths.join(link_package, fp_package, "BUILD.bazel"))
- rctx.file(build_file_path, "\n".join(generated_by_lines + [
- _ALIAS_TMPL.format(
- basename = paths.basename(fp_package),
- bazel_name = utils.bazel_name(fp_package),
- dir_suffix = utils.dir_suffix,
- direct_link_prefix = utils.direct_link_prefix,
- link_package = link_package,
- link_workspace = rctx.attr.pnpm_lock.workspace_name,
- ),
- ]))
-
- # Gather scoped packages
- if len(fp_package.split("/", 1)) > 1:
- package_scope = fp_package.split("/", 1)[0]
- build_file_package = paths.normalize(paths.join(link_package, package_scope))
- if build_file_package not in scoped_packages:
- scoped_packages[build_file_package] = []
- scoped_packages[build_file_package].append(
- "@{link_workspace}//{link_package}:{direct_link_prefix}{bazel_name}".format(
- bazel_name = utils.bazel_name(fp_package),
- direct_link_prefix = utils.direct_link_prefix,
- link_package = link_package,
- link_workspace = rctx.attr.pnpm_lock.workspace_name,
- ),
- )
+ if len(fp_package.split("/", 1)) > 1:
+ package_scope = fp_package.split("/", 1)[0]
+ defs_bzl_body.append(""" scoped_direct_targets["{package_scope}"].append(direct_targets[-1])""".format(
+ package_scope = package_scope,
+ ))
- # Generate linked_npm_packages target
+ # Generate catch all & scoped linked_npm_packages target
defs_bzl_body.append("""
+ for scope, scoped_targets in scoped_direct_targets.items():
+ linked_npm_packages(
+ name = "{}/{}".format(name, scope),
+ srcs = [t for t in scoped_targets if t],
+ tags = ["manual"],
+ visibility = ["//visibility:public"],
+ )
+
linked_npm_packages(
name = name,
srcs = [t for t in direct_targets if t],
@@ -609,16 +549,6 @@ def _impl(rctx):
visibility = ["//visibility:public"],
)""")
- # Generate scoped @npm//@scope targets
- for build_file_package, scope_packages in scoped_packages.items():
- rctx.file(paths.join(build_file_package, "BUILD.bazel"), "\n".join(generated_by_lines + [
- _SCOPE_TMPL.format(
- scope = paths.basename(build_file_package),
- srcs = starlark_codegen_utils.to_list_attr(scope_packages, 1),
- package_path = build_file_package,
- ),
- ]))
-
rctx.file(_DEFS_BZL_FILENAME, "\n".join(defs_bzl_header + [""] + defs_bzl_body + [""]))
rctx.file(_REPOSITORIES_BZL_FILENAME, "\n".join(repositories_bzl))
rctx.file("BUILD.bazel", "\n".join(generated_by_lines + [
diff --git a/npm/private/utils.bzl b/npm/private/utils.bzl
index b4472371c..4258b7422 100644
--- a/npm/private/utils.bzl
+++ b/npm/private/utils.bzl
@@ -93,11 +93,9 @@ utils = struct(
strip_peer_dep_version = _strip_peer_dep_version,
# Symlinked node_modules structure virtual store path under node_modules
virtual_store_root = ".aspect_rules_js",
- # Prefix for link_npm_package_direct links
- direct_link_prefix = "direct_link__",
# Prefix for link_npm_package_store links
store_link_prefix = "store_link__",
- # Suffix for package directory filegroup and alias targets
+ # Suffix for package directory filegroup
dir_suffix = "__dir",
# Suffix for npm_import links repository
links_suffix = "__links",