rollup/rollup-plugin-node-resolve

Symlinks are not correctly resolved on Unix

filipesilva opened this issue · 10 comments

I am getting this issue on Unix only. A repro can be found at https://github.com/filipesilva/node-resolve-unix-symlink-bug.

npm install
npm run symlink
(cd src && npm run rollup)

On Unix, this results in the following error (preceded by a bunch of The 'this' keyword is equivalent to 'undefined' warnings):

��   'Subject' is not exported by ../node_modules/rxjs/Subject.js
https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module
../node_modules/@angular/core/@angular/core.es5.js (14:9)
12: import { merge } from 'rxjs/observable/merge';
13: import { share } from 'rxjs/operator/share';
14: import { Subject } from 'rxjs/Subject';
             ^
15: /**
16:  * Creates a token that can be used in a DI Provider.

On Windows this error does not appear and instead I get #93. Note that creating symlinks requires admin privileges on Windows.

Doing npm install rollup-plugin-node-resolve@2.0.0 makes the behavior be the same on both platforms.

Thanks for the repro. Is there any way you can make a more minimal version, i.e. one that could form the basis for a test? It's very hard to understand what the actual problem is at the moment 😀

That's actually a bit hard for me, I don't have a unix machine myself. I can try some alternative setups hooking it up with Travis to test though.

Heya, I've been trying a couple of different setups with simple modules (instead of Angular and RxJs) but haven't had much success to be honest.

It seems to be related to detection of the module format breaking with there's a symlink. I cleaned up the output a bit and added a non-symlink comparison:

$ npm run rollup
> node-resolve-unix-symlink-bug@1.0.0 rollup /home/travis/build/filipesilva/node-resolve-unix-symlink-bug
> rollup -c
⚠️   'default' is imported from external module 'rollup' but never used
The command "npm run rollup" exited with 0.

$ (cd src && npm run rollup)
> inner-project@ rollup /home/travis/build/filipesilva/node-resolve-unix-symlink-bug/src
> rollup -c
⚠️   'default' is imported from external module 'rollup' but never used
🚨   'Subject' is not exported by ../node_modules/rxjs/Subject.js
https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module
../node_modules/@angular/core/@angular/core.es5.js (14:9)
12: import { merge } from 'rxjs/observable/merge';
13: import { share } from 'rxjs/operator/share';
14: import { Subject } from 'rxjs/Subject';
             ^
15: /**
16:  * Creates a token that can be used in a DI Provider.

The same rollup config is used in both cases, and the same entry point. When there is no symlink present, rollup finishes successfully. When there is a symlink, there seems to be some trouble figuring out what RxJs is exporting.

I have another branch (experiment) where I tried replacing Angular and RxJs with two simple local modules, but haven't been able to reproduce the behavior.

Do you have any idea of what might be going on? It could offer some insight on how to do a simple reproduction.

Ok, I think I finally figured it out. There's a simple repro at https://github.com/filipesilva/node-resolve-unix-symlink-bug master.

It seems to actually be also be related to rollup-plugin-commonjs.

When user code imports a ESM library that imports a CJS library (configured via rollup-plugin-commonjs) with non-symlinked node_modules, everything is fine:

0.79s$ npm run rollup
> node-resolve-unix-symlink-bug@1.0.0 rollup /home/travis/build/filipesilva/node-resolve-unix-symlink-bug
> rollup -c
⚠️   'default' is imported from external module 'rollup' but never used

The same code with a symlinked node_modules fails:

The command "npm run rollup" exited with 0.
0.78s$ (cd src && npm run rollup)
> inner-project@ rollup /home/travis/build/filipesilva/node-resolve-unix-symlink-bug/src
> rollup -c
⚠️   'default' is imported from external module 'rollup' but never used
🚨   'module2Value' is not exported by ../node_modules/module2/index.js
https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module
../node_modules/module1/index.js (1:9)
1: import { module2Value } from 'module2';
            ^
2: 
3: export const module1Value = module2Value + 'module1';
gms1 commented

this works for me using verson 2.0.0, but fails using version 2.1.0
no error, after commenting out the call to 'fs.realpathSync' ( which has been introduced in 2.1.0)the 'fs.realpathSync' resolves the symlink correctly

gms1 commented

My symlinked package is bundled by rollup, provides additional es6 modules to make rollup happy and defines all angular package dependencies as peer dependencies.
So I think (in this case?) all commonjs modules should never be resolved from the node_modules of the symlinked package, which is the case if the symlink gets resolved.

gms1 commented

node has the "preserve-symlinks" options as a workaround for not being able to correctly resolve peerDependencies of symlinked packages.
preserve_symlinks
Can this be a simple solution to this problem?

I'm having this problem on Mac OS as well. Is the current fix just downgrading to 2.0.0 or is there a better fix for this? What's the latest version available that symlinks are working in? 2.0.0 seems to work for me but right now 3.4.0 is the current version and I don't want to be too far behind.

Edit: I tested on 2.1.0 and 2.1.1 and neither work. So I'll stay on 2.0.0 for now.

I believe #98 and #100 are both duplicates of this issue. #100 offers a potential fix.

Edit: For anyone hitting this thread from google like I did. This comment has the answer for the latest version of rollup: #100 (comment)

resolve({
  main: false
})

This no longer repros. Probably fixed by some of the recent symlinking improvements across this plugin, rollup-plugin-commonjs, and browserify/resolve. Please re-open if this is still an issue!

Note that the above repro repo's usage of include/exclude for rollup-plugin-commonjs is incorrect when symlinks are involved. See rollup/rollup-plugin-commonjs#405 for the doc updates making usage clearer with respect to symlinks.