mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
build(bazel): fix race conditions in windows aio build
Disables the rules_nodejs linker and adds a custom esm module resolver
This commit is contained in:
committed by
Joey Perrott
parent
7c8ca113c1
commit
07126ae40f
+2
-1
@@ -1,5 +1,6 @@
|
||||
load("@aio_npm//@angular-devkit/architect-cli:index.bzl", "architect", "architect_test")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "npm_package_bin")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "npm_package_bin")
|
||||
load("//aio/tools:defaults.bzl", "nodejs_binary")
|
||||
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
|
||||
|
||||
# The write_source_files macro is used to write bazel outputs to the source tree and test that they are up to date.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "nodejs_binary")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||
load("//aio/tools:defaults.bzl", "nodejs_binary")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", _nodejs_binary = "nodejs_binary")
|
||||
|
||||
def nodejs_binary(data = [], env = {}, templated_args = [], **kwargs):
|
||||
data = data + [
|
||||
"//aio/tools/esm-loader",
|
||||
"//aio/tools/esm-loader:esm-loader.mjs",
|
||||
]
|
||||
|
||||
env = dict(env, **{"NODE_MODULES_WORKSPACE_NAME": "aio_npm"})
|
||||
|
||||
templated_args = templated_args + [
|
||||
# Disable the linker and rely on patched resolution which works better on Windows
|
||||
# and is less prone to race conditions when targets build concurrently.
|
||||
"--nobazel_run_linker",
|
||||
# Provide a custom esm loader to resolve third-party depenencies. Unlike for cjs
|
||||
# modules, rules_nodejs doesn't patch imports when the linker is disabled.
|
||||
"--node_options=--loader=./$(rootpath //aio/tools/esm-loader:esm-loader.mjs)",
|
||||
]
|
||||
|
||||
_nodejs_binary(
|
||||
data = data,
|
||||
env = env,
|
||||
templated_args = templated_args,
|
||||
**kwargs
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
package(default_visibility = ["//aio:__subpackages__"])
|
||||
|
||||
exports_files([
|
||||
"esm-loader.mjs",
|
||||
])
|
||||
|
||||
filegroup(
|
||||
name = "esm-loader",
|
||||
srcs = [
|
||||
"esm-loader.mjs",
|
||||
"//third_party/github.com/lukeed/resolve.exports",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,56 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {pathToFileURL} from 'url';
|
||||
import {resolve as resolveExports} from '../../../third_party/github.com/lukeed/resolve.exports/index.mjs';
|
||||
|
||||
/*
|
||||
Custom module loader (see https://nodejs.org/api/cli.html#--experimental-loadermodule) to support
|
||||
loading third-party packages in esm modules when the rules_nodejs linker is disabled. Resolves
|
||||
third-party imports from the node_modules folder in the bazel workspace defined by
|
||||
process.env.NODE_MODULES_WORKSPACE_NAME, and uses default resolution for all other imports.
|
||||
|
||||
This is required because rules_nodejs only patches requires in cjs modules when the linker
|
||||
is disabled, not imports in mjs modules.
|
||||
*/
|
||||
export async function resolve(specifier, context, defaultResolve) {
|
||||
if (!isNodeOrNpmPackageImport(specifier)) {
|
||||
return defaultResolve(specifier, context, defaultResolve);
|
||||
}
|
||||
|
||||
const nodeModules = path.resolve('external', process.env.NODE_MODULES_WORKSPACE_NAME, 'node_modules');
|
||||
|
||||
const packageImport = parsePackageImport(specifier);
|
||||
const pathToNodeModule = path.join(nodeModules, packageImport.packageName);
|
||||
|
||||
const isInternalNodePackage = !fs.existsSync(pathToNodeModule);
|
||||
if (isInternalNodePackage) {
|
||||
return defaultResolve(specifier, context, defaultResolve);
|
||||
}
|
||||
|
||||
const packageJson = JSON.parse(fs.readFileSync(path.join(pathToNodeModule, 'package.json'), 'utf-8'));
|
||||
|
||||
const localPackagePath = resolvePackageLocalFilepath(packageImport, packageJson);
|
||||
const resolvedFilePath = path.join(pathToNodeModule, localPackagePath);
|
||||
|
||||
return {url: pathToFileURL(resolvedFilePath).href};
|
||||
}
|
||||
|
||||
function isNodeOrNpmPackageImport(specifier) {
|
||||
return !specifier.startsWith('./') && !specifier.startsWith('../') && !specifier.startsWith('node:') && !specifier.startsWith('file:');
|
||||
}
|
||||
|
||||
function parsePackageImport(specifier) {
|
||||
const [, packageName, pathInPackage = ''] = /^((?:@[^/]+\/)?[^/]+)(?:\/(.+))?$/.exec(specifier) ?? [];
|
||||
if (!packageName) {
|
||||
throw new Error(`Could not parse package name import statement '${specifier}'`);
|
||||
}
|
||||
return {packageName, pathInPackage, specifier};
|
||||
}
|
||||
|
||||
function resolvePackageLocalFilepath(packageImport, packageJson) {
|
||||
if (packageJson.exports) {
|
||||
return resolveExports(packageJson, packageImport.specifier);
|
||||
}
|
||||
|
||||
return packageImport.pathInPackage || packageJson.module || packageJson.main || 'index.js';
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
|
||||
load("//aio/tools:defaults.bzl", "nodejs_binary")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
@@ -7,13 +7,11 @@ nodejs_binary(
|
||||
data = [
|
||||
"exampleZipper.mjs",
|
||||
"//aio/tools/transforms/examples-package",
|
||||
"//aio/tools/transforms/helpers",
|
||||
"@aio_npm//archiver",
|
||||
"@aio_npm//canonical-path",
|
||||
"@aio_npm//fs-extra",
|
||||
"@aio_npm//globby",
|
||||
],
|
||||
entry_point = "generateZip.mjs",
|
||||
# --preserve-symlinks-main is not enabled by default (see https://github.com/bazelbuild/rules_nodejs/pull/2176)
|
||||
# However it seems to be required for mjs entry points to resolve node_modules within the sandbox.
|
||||
templated_args = ["--node_options=--preserve-symlinks-main"],
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ import fs from 'fs-extra';
|
||||
import {globbySync} from 'globby';
|
||||
import {fileURLToPath} from 'url';
|
||||
|
||||
import regionExtractor from 'aio/tools/examples-package/services/region-parser.js';
|
||||
import regionExtractor from '../transforms/examples-package/services/region-parser.js';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const EXAMPLE_CONFIG_NAME = 'example-config.json';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
|
||||
load("//aio/tools:defaults.bzl", "nodejs_binary")
|
||||
load("@aio_npm//@bazel/jasmine:index.bzl", "jasmine_node_test")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
|
||||
load("//aio/tools:defaults.bzl", "nodejs_binary")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
@@ -7,13 +7,11 @@ nodejs_binary(
|
||||
data = [
|
||||
"builder.mjs",
|
||||
"//aio/tools/transforms/examples-package",
|
||||
"//aio/tools/transforms/helpers",
|
||||
"@aio_npm//canonical-path",
|
||||
"@aio_npm//fs-extra",
|
||||
"@aio_npm//globby",
|
||||
"@aio_npm//jsdom",
|
||||
],
|
||||
entry_point = "generateStackblitz.mjs",
|
||||
# --preserve-symlinks-main is not enabled by default (see https://github.com/bazelbuild/rules_nodejs/pull/2176)
|
||||
# However it seems to be required for mjs entry points to resolve node_modules within the sandbox.
|
||||
templated_args = ["--node_options=--preserve-symlinks-main"],
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import fs from 'fs-extra';
|
||||
import {globbySync} from 'globby';
|
||||
import jsdom from 'jsdom';
|
||||
|
||||
import regionExtractor from 'aio/tools/examples-package/services/region-parser.js';
|
||||
import regionExtractor from '../transforms/examples-package/services/region-parser.js';
|
||||
|
||||
export class StackblitzBuilder {
|
||||
constructor(examplePath, destPath) {
|
||||
|
||||
@@ -3,7 +3,6 @@ load("@aio_npm//@bazel/jasmine:index.bzl", "jasmine_node_test")
|
||||
|
||||
js_library(
|
||||
name = "examples-package",
|
||||
package_name = "aio/tools/examples-package",
|
||||
srcs = glob(
|
||||
["**/*.js"],
|
||||
exclude = ["**/*.spec.js"],
|
||||
|
||||
@@ -4,7 +4,7 @@ const inlineC = require('./region-matchers/inline-c');
|
||||
const inlineCOnly = require('./region-matchers/inline-c-only');
|
||||
const inlineHash = require('./region-matchers/inline-hash');
|
||||
const DEFAULT_PLASTER = '. . .';
|
||||
const {mapObject} = require('helpers/utils');
|
||||
const {mapObject} = require('../../helpers/utils');
|
||||
const removeEslintComments = require('./removeEslintComments');
|
||||
|
||||
module.exports = function regionParser() {
|
||||
|
||||
@@ -3,12 +3,11 @@ load("@aio_npm//@bazel/jasmine:index.bzl", "jasmine_node_test")
|
||||
|
||||
js_library(
|
||||
name = "helpers",
|
||||
package_name = "helpers",
|
||||
srcs = [
|
||||
"test-package.js",
|
||||
"utils.js",
|
||||
],
|
||||
visibility = ["//aio/tools/transforms:__subpackages__"],
|
||||
visibility = ["//aio/tools:__subpackages__"],
|
||||
deps = [
|
||||
"//:package_json",
|
||||
"@aio_npm//canonical-path",
|
||||
|
||||
Reference in New Issue
Block a user