@@ -144,7 +144,7 @@ export async function main() {
144144 // find all packages (including packages in nested node_modules)
145145 const pkgs : Dep [ ] = [ ] ;
146146
147- await findPackagesAndPush ( pkgs , 'node_modules' , deps ) ;
147+ await findPackagesAndPush ( pkgs , nodeModulesFolder ( ) , deps ) ;
148148
149149 // Sort the files to ensure the order
150150 pkgs . sort ( compareDep ) ;
@@ -162,6 +162,12 @@ export async function main() {
162162 await writeFile ( '.bazelignore' , `node_modules\n${ config . workspace_rerooted_path } ` ) ;
163163}
164164
165+ function nodeModulesFolder ( ) : string {
166+ return config . exports_directories_only ?
167+ `${ config . workspace_rerooted_package_json_dir } /node_modules` :
168+ 'node_modules' ;
169+ }
170+
165171/**
166172 * Generates all build files
167173 */
@@ -206,7 +212,7 @@ function flattenDependencies(pkgs: Dep[]) {
206212async function generateRootBuildFile ( pkgs : Dep [ ] ) {
207213 let buildFile = config . exports_directories_only ?
208214 printRootExportsDirectories ( pkgs ) :
209- printRoot ( pkgs ) ;
215+ printRootExportsAllFiles ( pkgs ) ;
210216
211217 // Add the manual build file contents if they exists
212218 try {
@@ -219,15 +225,27 @@ async function generateRootBuildFile(pkgs: Dep[]) {
219225 await writeFile ( 'BUILD.bazel' , buildFile ) ;
220226}
221227
228+
222229function printRootExportsDirectories ( pkgs : Dep [ ] ) {
223230 let filegroupsStarlark = '' ;
224- pkgs . forEach ( pkg => filegroupsStarlark += `filegroup(
225- name = "${ pkg . _dir . replace ( "/" , "_" ) } __source_directory",
226- srcs = ["node_modules/${ pkg . _dir } "],
227- visibility = ["@${ config . workspace } //:__subpackages__"],
231+ pkgs . forEach ( pkg => {
232+ filegroupsStarlark += `
233+ copy_file(
234+ name = "node_modules/${ pkg . _dir } ",
235+ src = "${ config . workspace_rerooted_package_json_dir } /node_modules/${ pkg . _dir } ",
236+ is_directory = True,
237+ out = "node_modules/${ pkg . _dir } ",
238+ visibility = ["//visibility:public"],
228239)
229-
230- ` ) ;
240+ js_library(
241+ name = "${ pkg . _dir . replace ( "/" , "_" ) } __contents",
242+ package_name = "${ pkg . _dir } ",
243+ package_path = "${ config . package_path } ",
244+ strip_prefix = "node_modules/${ pkg . _dir } ",
245+ srcs = [":node_modules/${ pkg . _dir } "],
246+ visibility = ["//:__subpackages__"],
247+ )
248+ ` } ) ;
231249
232250let depsStarlark = '' ;
233251if ( pkgs . length ) {
@@ -240,7 +258,11 @@ if (pkgs.length) {
240258
241259 const result =
242260 generateBuildFileHeader ( ) + `load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
261+ load("@build_bazel_rules_nodejs//third_party/github.com/bazelbuild/bazel-skylib:rules/copy_file.bzl", "copy_file")
243262
263+ # To support remote-execution, we must create a tree artifacts from the source directories.
264+ # We make the output node_modules/pkg_dir so that we get a free node_modules
265+ # tree in bazel-out and runfiles for this external repository.
244266${ filegroupsStarlark }
245267
246268# The node_modules directory in one catch-all js_library
@@ -251,7 +273,7 @@ js_library(
251273 return result
252274}
253275
254- function printRoot ( pkgs : Dep [ ] ) {
276+ function printRootExportsAllFiles ( pkgs : Dep [ ] ) {
255277 let pkgFilesStarlark = '' ;
256278 if ( pkgs . length ) {
257279 let list = '' ;
@@ -312,8 +334,10 @@ async function generatePackageBuildFiles(pkg: Dep) {
312334 if ( pkg . _files . includes ( 'BUILD' ) ) buildFilePath = 'BUILD' ;
313335 if ( pkg . _files . includes ( 'BUILD.bazel' ) ) buildFilePath = 'BUILD.bazel' ;
314336
337+ const nodeModules = nodeModulesFolder ( ) ;
338+
315339 // Recreate the pkg dir inside the node_modules folder
316- const nodeModulesPkgDir = `node_modules /${ pkg . _dir } ` ;
340+ const nodeModulesPkgDir = `${ nodeModules } /${ pkg . _dir } ` ;
317341 // Check if the current package dep dir is a symlink (which happens when we
318342 // install a node_module with link:)
319343 const isPkgDirASymlink = await fs . lstat ( nodeModulesPkgDir )
@@ -334,10 +358,10 @@ async function generatePackageBuildFiles(pkg: Dep) {
334358 // The following won't be used in a symlink build file case
335359 let buildFile = config . exports_directories_only ?
336360 printPackageExportsDirectories ( pkg ) :
337- printPackage ( pkg ) ;
361+ printPackageLegacy ( pkg ) ;
338362 if ( buildFilePath ) {
339363 buildFile = buildFile + '\n' +
340- await fs . readFile ( path . join ( 'node_modules' , pkg . _dir , buildFilePath ) , 'utf-8' ) ;
364+ await fs . readFile ( path . join ( nodeModules , pkg . _dir , buildFilePath ) , 'utf-8' ) ;
341365 } else {
342366 buildFilePath = 'BUILD.bazel' ;
343367 }
@@ -377,7 +401,7 @@ async function generatePackageBuildFiles(pkg: Dep) {
377401 if ( basenameUc === '_BUILD' || basenameUc === '_BUILD.BAZEL' ) {
378402 destFile = path . posix . join ( path . dirname ( destFile ) , basename . substr ( 1 ) ) ;
379403 }
380- const src = path . posix . join ( 'node_modules' , pkg . _dir , file ) ;
404+ const src = path . posix . join ( nodeModules , pkg . _dir , file ) ;
381405 await prev ;
382406 await mkdirp ( path . dirname ( destFile ) ) ;
383407 await fs . copyFile ( src , destFile ) ;
@@ -452,6 +476,7 @@ load("@build_bazel_rules_nodejs//internal/copy_repository:copy_repository.bzl",
452476 // Copy all files for this workspace to a folder under _workspaces
453477 // to restore the Bazel files which have be renamed from the npm package
454478 const workspaceSourcePath = path . posix . join ( '_workspaces' , workspace ) ;
479+ const nodeModules = nodeModulesFolder ( ) ;
455480 await mkdirp ( workspaceSourcePath ) ;
456481 await Promise . all ( pkg . _files . map ( async ( file ) => {
457482 if ( / ^ n o d e _ m o d u l e s [ / \\ ] / . test ( file ) ) {
@@ -471,7 +496,7 @@ load("@build_bazel_rules_nodejs//internal/copy_repository:copy_repository.bzl",
471496 if ( basenameUc === '_BUILD' || basenameUc === '_BUILD.BAZEL' ) {
472497 destFile = path . posix . join ( path . dirname ( destFile ) , basename . substr ( 1 ) ) ;
473498 }
474- const src = path . posix . join ( 'node_modules' , pkg . _dir , file ) ;
499+ const src = path . posix . join ( nodeModules , pkg . _dir , file ) ;
475500 const dest = path . posix . join ( workspaceSourcePath , destFile ) ;
476501 await mkdirp ( path . dirname ( dest ) ) ;
477502 await fs . copyFile ( src , dest ) ;
@@ -517,7 +542,7 @@ async function generateScopeBuildFiles(scope: string, pkgs: Dep[]) {
517542
518543 let buildFile = config . exports_directories_only ?
519544 printScopeExportsDirectories ( scope , deps ) :
520- printScope ( scope , deps ) ;
545+ printScopeLegacy ( scope , deps ) ;
521546 await writeFile ( path . posix . join ( scope , 'BUILD.bazel' ) , buildFile ) ;
522547}
523548
@@ -676,7 +701,7 @@ async function findPackagesAndPush(pkgs: Dep[], p: string, dependencies: Set<str
676701 * Finds and returns an array of all package scopes in node_modules.
677702 */
678703async function findScopes ( ) {
679- const p = 'node_modules' ;
704+ const p = nodeModulesFolder ( ) ;
680705 if ( ! await isDirectory ( p ) ) {
681706 return [ ] ;
682707 }
@@ -688,8 +713,8 @@ async function findScopes() {
688713 if ( ! f . startsWith ( '@' ) ) return ;
689714 f = path . posix . join ( p , f ) ;
690715 if ( await isDirectory ( f ) ) {
691- // strip 'node_modules/ ' from filename
692- return f . substring ( 'node_modules/' . length ) ;
716+ // strip leading 'node_modules' from filename
717+ return f . substring ( p . length + 1 ) ;
693718 }
694719 } )
695720 ) )
@@ -709,10 +734,10 @@ export async function parsePackage(p: string, dependencies: Set<string> = new Se
709734 const pkg = ( await isFile ( packageJson ) ) ?
710735 JSON . parse ( stripBom ( await fs . readFile ( packageJson , { encoding : 'utf8' } ) ) ) :
711736 { version : '0.0.0' } ;
712-
737+
713738 // Trim the leading node_modules from the path and
714739 // assign to _dir for future use
715- pkg . _dir = p . substring ( 'node_modules/' . length ) ;
740+ pkg . _dir = p . substring ( nodeModulesFolder ( ) . length + 1 ) ;
716741
717742 // Stash the package directory name for future use
718743 pkg . _name = pkg . _dir . split ( '/' ) . pop ( ) ;
@@ -1049,64 +1074,27 @@ function printPackageExportsDirectories(pkg: Dep) {
10491074 // Flattened list of direct and transitive dependencies hoisted to root by the package manager
10501075 const deps = [ pkg ] . concat ( pkg . _dependencies . filter ( dep => dep !== pkg && ! dep . _isNested ) ) ;
10511076 const depsStarlark =
1052- deps . map ( dep => `"//${ dep . _dir } : ${ dep . _name } __contents",` ) . join ( '\n ' ) ;
1077+ deps . map ( dep => `"//: ${ dep . _dir . replace ( "/" , "_" ) } __contents",` ) . join ( '\n ' ) ;
10531078
10541079 return `load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
1055- load("@build_bazel_rules_nodejs//third_party/github.com/bazelbuild/bazel-skylib:rules/copy_file.bzl", "copy_file")
10561080
10571081# Generated targets for npm package "${ pkg . _dir } "
10581082${ printJson ( pkg ) }
10591083
1060- # To support remote-execution, we must create a tree artifact from the source directory
1061- copy_file(
1062- name = "directory",
1063- src = "@${ config . workspace } //:${ pkg . _dir . replace ( "/" , "_" ) } __source_directory",
1064- is_directory = True,
1065- out = "tree",
1066- )
1067-
10681084# The primary target for this package for use in rule deps
10691085js_library(
10701086 name = "${ pkg . _name } ",
10711087 deps = [
10721088 ${ depsStarlark }
10731089 ],
10741090)
1075-
1076- # Target is used as dep for main targets to prevent circular dependencies errors
1077- js_library(
1078- name = "contents",
1079- package_name = "${ pkg . _dir } ",
1080- package_path = "${ config . package_path } ",
1081- strip_prefix = "tree",
1082- srcs = [":directory"],
1083- visibility = ["//:__subpackages__"],
1084- )
1085-
1086- # For ts_library backward compat which uses @npm//typescript:__files
1087- alias(
1088- name = "${ pkg . _name } __files",
1089- actual = "directory",
1090- )
1091-
1092- # For ts_library backward compat which uses @npm//typescript:__files
1093- alias(
1094- name = "${ pkg . _name } __contents",
1095- actual = "contents",
1096- )
1097-
1098- # For ts_library backward compat which uses @npm//typescript:typescript__typings
1099- alias(
1100- name = "${ pkg . _name } __typings",
1101- actual = "contents",
1102- )
11031091` ;
11041092}
11051093
11061094/**
11071095 * Given a pkg, return the skylark `js_library` targets for the package.
11081096 */
1109- function printPackage ( pkg : Dep ) {
1097+ function printPackageLegacy ( pkg : Dep ) {
11101098 function starlarkFiles ( attr : string , files : string [ ] , comment : string = '' ) {
11111099 return `
11121100 ${ comment ? comment + '\n ' : '' } ${ attr } = [
@@ -1316,7 +1304,7 @@ export function printPackageBin(pkg: Dep) {
13161304
13171305 for ( const [ name , path ] of executables . entries ( ) ) {
13181306 const entryPoint = config . exports_directories_only ?
1319- `{ "@${ config . workspace } //${ pkg . _dir } :directory ": "${ path } " }` :
1307+ `{ "@${ config . workspace } //:node_modules/ ${ pkg . _dir } ": "${ path } " }` :
13201308 `"@${ config . workspace } //:node_modules/${ pkg . _dir } /${ path } "` ;
13211309 result += `# Wire up the \`bin\` entry \`${ name } \`
13221310nodejs_binary(
@@ -1346,7 +1334,7 @@ export function printIndexBzl(pkg: Dep) {
13461334
13471335 for ( const [ name , path ] of executables . entries ( ) ) {
13481336 const entryPoint = config . exports_directories_only ?
1349- `{ "@${ config . workspace } //${ pkg . _dir } :directory ": "${ path } " }` :
1337+ `{ "@${ config . workspace } //:node_modules/ ${ pkg . _dir } ": "${ path } " }` :
13501338 `"@${ config . workspace } //:node_modules/${ pkg . _dir } /${ path } "` ;
13511339 result = `${ result }
13521340
@@ -1391,7 +1379,7 @@ type Dep = {
13911379/**
13921380 * Given a scope, return the skylark `js_library` target for the scope.
13931381 */
1394- function printScope ( scope : string , deps : Dep [ ] ) {
1382+ function printScopeLegacy ( scope : string , deps : Dep [ ] ) {
13951383 let pkgFilesStarlark = '' ;
13961384 if ( deps . length ) {
13971385 const list = deps . map ( dep => `"//${ dep . _dir } :${ dep . _name } __files",` ) . join ( '\n ' ) ;
0 commit comments