@@ -424,6 +424,9 @@ export async function main(args: string[], runfiles: Runfiles) {
424
424
const isExecroot = startCwd == execroot ;
425
425
log_verbose ( 'isExecroot:' , isExecroot . toString ( ) ) ;
426
426
427
+ const isBazelRun = ! ! process . env [ 'BUILD_WORKSPACE_DIRECTORY' ]
428
+ log_verbose ( 'isBazelRun:' , isBazelRun . toString ( ) ) ;
429
+
427
430
if ( ! isExecroot && execroot ) {
428
431
// If we're not in the execroot and we've found one then change to the execroot
429
432
// directory to create the node_modules symlinks
@@ -481,55 +484,66 @@ export async function main(args: string[], runfiles: Runfiles) {
481
484
workspaceNodeModules = undefined ;
482
485
}
483
486
487
+ let primaryNodeModules ;
484
488
if ( packagePath ) {
485
- // In some cases packagePath may not exist in sandbox if there are no source deps
486
- // and only generated file deps. we create it so that we that we can link to
487
- // packagePath/node_modules since packagePathBin/node_modules is a symlink to
488
- // packagePath/node_modules and is unguarded in launcher.sh as we allow symlinks to fall
489
- // through to from output tree to source tree to prevent resolving the same npm package to
490
- // multiple locations on disk
491
- await mkdirp ( packagePath ) ;
492
- }
493
-
494
- // There are third party modules at this package path
495
- const execrootNodeModules = path . posix . join ( packagePath , `node_modules` ) ;
489
+ const binNodeModules = path . posix . join ( bin , packagePath , 'node_modules' ) ;
490
+ await mkdirp ( path . dirname ( binNodeModules ) ) ;
491
+
492
+ // Create bin/<package_path>/node_modules symlink
493
+ // (or empty directory if there are no 3rd party deps to symlink to)
494
+ if ( workspaceNodeModules ) {
495
+ await symlinkWithUnlink ( workspaceNodeModules , binNodeModules ) ;
496
+ primaryNodeModules = workspaceNodeModules ;
497
+ } else {
498
+ await mkdirp ( binNodeModules ) ;
499
+ primaryNodeModules = binNodeModules ;
500
+ }
496
501
497
- if ( workspaceNodeModules ) {
498
- // Execroot symlink -> external workspace node_modules
499
- await symlinkWithUnlink ( workspaceNodeModules , execrootNodeModules ) ;
502
+ if ( ! isBazelRun ) {
503
+ // Special case under bazel run where we don't want to create node_modules
504
+ // in an execroot under a package path as this will end up in the user's
505
+ // workspace via the package path folder symlink
506
+ const execrootNodeModules = path . posix . join ( packagePath , 'node_modules' ) ;
507
+ await mkdirp ( path . dirname ( execrootNodeModules ) ) ;
508
+ await symlinkWithUnlink ( primaryNodeModules , execrootNodeModules ) ;
509
+ }
500
510
} else {
501
- // Create an execroot node_modules directory since there are no third party node_modules to symlink to
502
- await mkdirp ( execrootNodeModules ) ;
503
- }
511
+ const execrootNodeModules = 'node_modules' ;
504
512
505
- if ( packagePath ) {
506
- // Bin symlink -> execroot node_modules
507
- // NB: don't do this for the root of the bin tree since standard node_modules resolution
508
- // will fall back to the execroot node_modules naturally
509
- // See https://github.com/bazelbuild/rules_nodejs/issues/3054
510
- const packagePathBin = path . posix . join ( bin , packagePath ) ;
511
- await mkdirp ( `${ packagePathBin } ` ) ;
512
- await symlinkWithUnlink ( execrootNodeModules , `${ packagePathBin } /node_modules` ) ;
513
+ // Create execroot/node_modules symlink (or empty directory if there are
514
+ // no 3rd party deps to symlink to)
515
+ if ( workspaceNodeModules ) {
516
+ await symlinkWithUnlink ( workspaceNodeModules , execrootNodeModules ) ;
517
+ primaryNodeModules = workspaceNodeModules ;
518
+ } else {
519
+ await mkdirp ( execrootNodeModules ) ;
520
+ primaryNodeModules = execrootNodeModules ;
521
+ }
522
+
523
+ // NB: Don't create a bin/node_modules since standard node_modules
524
+ // resolution will fall back to the execroot node_modules naturally. See
525
+ // https://github.com/bazelbuild/rules_nodejs/issues/3054
513
526
}
514
527
515
- // Start CWD symlink -> execroot node_modules
528
+ // If start cwd was in runfiles then create
529
+ // start/cwd
516
530
if ( ! isExecroot ) {
517
- const runfilesPackagePath = path . posix . join ( startCwd , packagePath ) ;
518
- await mkdirp ( ` ${ runfilesPackagePath } ` ) ;
531
+ const runfilesNodeModules = path . posix . join ( startCwd , packagePath , 'node_modules' ) ;
532
+ await mkdirp ( path . dirname ( runfilesNodeModules ) ) ;
519
533
// Don't link to the root execroot node_modules if there is a workspace node_modules.
520
534
// Bazel will delete that symlink on rebuild in the ibazel run context.
521
- await symlinkWithUnlink ( ! packagePath && workspaceNodeModules ? workspaceNodeModules : execrootNodeModules , ` ${ runfilesPackagePath } /node_modules` ) ;
535
+ await symlinkWithUnlink ( primaryNodeModules , runfilesNodeModules ) ;
522
536
}
523
537
524
538
// RUNFILES symlink -> execroot node_modules
525
539
if ( process . env [ 'RUNFILES' ] ) {
526
540
const stat = await gracefulLstat ( process . env [ 'RUNFILES' ] ) ;
527
541
if ( stat && stat . isDirectory ( ) ) {
528
- const runfilesPackagePath = path . posix . join ( process . env [ 'RUNFILES' ] , workspace , packagePath ) ;
529
- await mkdirp ( ` ${ runfilesPackagePath } ` ) ;
542
+ const runfilesNodeModules = path . posix . join ( process . env [ 'RUNFILES' ] , workspace , 'node_modules' ) ;
543
+ await mkdirp ( path . dirname ( runfilesNodeModules ) ) ;
530
544
// Don't link to the root execroot node_modules if there is a workspace node_modules.
531
545
// Bazel will delete that symlink on rebuild in the ibazel run context.
532
- await symlinkWithUnlink ( ! packagePath && workspaceNodeModules ? workspaceNodeModules : execrootNodeModules , ` ${ runfilesPackagePath } /node_modules` ) ;
546
+ await symlinkWithUnlink ( primaryNodeModules , runfilesNodeModules ) ;
533
547
}
534
548
}
535
549
}
@@ -593,7 +607,9 @@ export async function main(args: string[], runfiles: Runfiles) {
593
607
}
594
608
595
609
async function linkModules ( package_path : string , m : LinkerTreeElement ) {
596
- const symlinkIn = package_path ? `${ package_path } /node_modules` : 'node_modules' ;
610
+ const symlinkIn = package_path ?
611
+ path . posix . join ( bin , package_path , 'node_modules' ) :
612
+ 'node_modules' ;
597
613
598
614
// ensure the parent directory exist
599
615
if ( path . dirname ( m . name ) ) {
0 commit comments