diff --git a/nodejs/rules.bzl b/nodejs/rules.bzl index c1d4753..a4ddb60 100644 --- a/nodejs/rules.bzl +++ b/nodejs/rules.bzl @@ -260,7 +260,11 @@ def _nodejs_binary_impl(ctx): runfiles = runfiles, ) - return [default_info] + # PnP resolves this binary's modules without materializing node_modules, so + # a filesystem view of the package tree no longer exists. Forward the + # CommonJS graph -- in the binary's own configuration -- for rules that + # still need one, such as webpack_server. + return [default_info] + ([cjs_dep] if cjs_dep else []) def _nodejs_transition_impl(settings, attrs): return {"//javascript:module": "node"} diff --git a/webpack/providers.bzl b/webpack/providers.bzl index 872a2f7..7c6cb5b 100644 --- a/webpack/providers.bzl +++ b/webpack/providers.bzl @@ -3,6 +3,7 @@ WebpackInfo = provider( fields = { "bin": "Webpack executable", "server": "Webpack server executable", + "server_cjs": "Webpack server CommonJS packages", "client_cjs": "Webpack dev server lib", "client_js": "Webpack dev server lib", "config_path": "Config path", diff --git a/webpack/rules.bzl b/webpack/rules.bzl index 292d4a4..be411c4 100644 --- a/webpack/rules.bzl +++ b/webpack/rules.bzl @@ -39,6 +39,7 @@ def _webpack_impl(ctx): config = ctx.attr.config config_dep = ctx.attr.config_dep[CjsInfo] server = ctx.attr.server[DefaultInfo] + server_cjs = ctx.attr.server[CjsInfo] webpack_info = WebpackInfo( bin = bin, @@ -46,6 +47,7 @@ def _webpack_impl(ctx): client_js = client_js, config_path = "%s/%s" % (to_rlocation_path(ctx, config_dep.package), config), server = server, + server_cjs = server_cjs, ) return [webpack_info] @@ -76,6 +78,7 @@ webpack = rule( cfg = "exec", executable = True, mandatory = True, + providers = [CjsInfo], ), "client": attr.label_list( mandatory = True, @@ -270,6 +273,7 @@ def _webpack_server_impl(ctx): source_map = ctx.attr._source_map[BuildSettingInfo].value webpack = ctx.split_attr.webpack["tool"][WebpackInfo] webpack_client = ctx.split_attr.webpack["browser"][WebpackInfo] + server_cjs = webpack.server_cjs dep_js = ctx.attr.dep[0][JsInfo] dep_cjs = ctx.attr.dep[0][CjsInfo] name = ctx.attr.name @@ -299,6 +303,23 @@ def _webpack_server_impl(ctx): package_path = package_path, ) + def node_package_path(package): + return to_rlocation_path(rlocation_ctx, package) + + # The webpack tools resolve their own modules through PnP, but the dev + # server bundles files out of that tree -- webpack's hot client and the + # entries plugins inject -- and webpack resolves those from the filesystem. + # The shim links the tree back in from this manifest. + node_package_manifest = actions.declare_file("%s-node-packages.json" % name) + gen_manifest( + actions = actions, + manifest_bin = ctx.attr._manifest[DefaultInfo], + manifest = node_package_manifest, + packages = server_cjs.transitive_packages, + deps = server_cjs.transitive_links, + package_path = node_package_path, + ) + js_info = JsInfo( transitive_files = depset(transitive = [js_info.transitive_files for js_info in [dep_js] + webpack_client.client_js]), ) @@ -320,6 +341,7 @@ def _webpack_server_impl(ctx): "%{digest}": shell.quote(to_rlocation_path(ctx, src_digest)), "%{input_root}": shell.quote(package_path(dep_cjs.package)), "%{js_source_map}": shell.quote(json.encode(source_map)), + "%{node_package_manifest}": shell.quote(to_rlocation_path(ctx, node_package_manifest)), "%{package_manifest}": shell.quote(to_rlocation_path(ctx, package_manifest)), "%{runtime}": shell.quote(to_rlocation_path(ctx, runtime)), "%{shim}": shell.quote(to_rlocation_path(ctx, shim)), @@ -339,6 +361,7 @@ def _webpack_server_impl(ctx): runfiles = ctx.runfiles( files = [ + node_package_manifest, package_manifest, runtime, shim, diff --git a/webpack/server-runner.sh.tpl b/webpack/server-runner.sh.tpl index 1156073..9ad16d0 100644 --- a/webpack/server-runner.sh.tpl +++ b/webpack/server-runner.sh.tpl @@ -22,6 +22,7 @@ function abspath () { export COMPILATION_MODE=%{compilation_mode} export NODE_OPTIONS_APPEND="-r $(abspath "$RUNFILES_DIR"/%{runtime}/index.js) -r $(abspath "$RUNFILES_DIR"/%{shim}/index.js)" export JS_SOURCE_MAP=%{js_source_map} +export NODE_PACKAGE_MANIFEST="$RUNFILES_DIR"/%{node_package_manifest} export WATCHPACK_POLLING=130929 export WEBPACK_CONFIG="$RUNFILES_DIR"/%{config} export WEBPACK_DIGEST="$RUNFILES_DIR"/%{digest}