New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modules are executed multiple times when using symlinks in node_modules #1063

Closed
epeli opened this Issue Jan 9, 2015 · 12 comments

Comments

Projects
None yet
9 participants
@epeli
Copy link
Contributor

epeli commented Jan 9, 2015

I have following symlink in my project

ln -sf .. node_modules/app

and I require modules like this

var config = require("app/config");

etc.

but in this case the config module is executed multiple times when it is required from different js files.

Here's smallest possible example reproducing this https://github.com/epeli/browserify-bug

This bug was introduced in the 8.0.0 release.

The symlink idea is from the browserify handbook https://github.com/substack/browserify-handbook#symlink

@epeli

This comment has been minimized.

Copy link
Contributor Author

epeli commented Jan 9, 2015

This commit breaks the example code 3249915

@epeli

This comment has been minimized.

Copy link
Contributor Author

epeli commented Jan 9, 2015

Also after inspecting the generated bundle the config.js is not duplicated in the bundle. It's just executed twice.

bundle.js https://gist.github.com/3e618c5b85f9516b024a

@epeli epeli changed the title Modules are executed multiple times when using symlinks node_modules Modules are executed multiple times when using symlinks in node_modules Jan 9, 2015

@ashaffer

This comment has been minimized.

Copy link
Member

ashaffer commented Jan 9, 2015

+1

@feross

This comment has been minimized.

Copy link
Member

feross commented Jan 11, 2015

@epeli Thanks for proving an example. I confirmed that this is indeed a bug in browserify.

@spudly

This comment has been minimized.

Copy link

spudly commented Feb 9, 2015

Same problem here, but I'm not using symlinks. I have four modules that all require the same version of the same package. That package is included once, but executed 4 times.

@timoxley

This comment has been minimized.

Copy link
Contributor

timoxley commented Feb 23, 2015

have experimented at length with various solutions to this and not easy to have browserify only pay attention to realpaths as it seems to require realpath awareness across multiple modules and pipeline steps. Even with various hacks I couldn't get browserify/watchify to work reliably with symlinked packages.

Likely I just have NFI what I'm doing though, would appreciate @substack perhaps pointing in the right direction how to make browserify/watchify symlink aware.

@jamieowen

This comment has been minimized.

Copy link

jamieowen commented May 11, 2015

+1

@chrisirhc

This comment has been minimized.

Copy link
Contributor

chrisirhc commented Jun 29, 2015

After doing a lot of digging, I found that this behavior is intentional and by design according to #1027 and 4c04362. More about this on the changelog for 8.0.0.
It seems that the module will always be re-initialized even if they're identical.

I think people working with common libraries (e.g. three.js and react) might want an aggressive version of dedupe that actually reuses the same instance. Perhaps this feature can be opt-in, such as an option called dedupeInstance (#1317)?

@dogada

This comment has been minimized.

Copy link

dogada commented Jun 30, 2015

I don't think this behavior is intentional. Ticket #1027 resolves issue with importing of different modules with same content. But in our case we import same module in different places, so we should receive same module instance everywhere as it works in Node.

I resolved this issue for myself by moving dependency that MUST be singleton to the own standalone module that I access via global variable in rest of NPM-modules of my application. Not too nice but works.

@rikukissa

This comment has been minimized.

Copy link

rikukissa commented Jun 30, 2015

We've been struggling with this problem also. One temporary "solution" we found was to use browserify-resolutions which seems to handle this problem in most cases. I would still like to see an example of how this should be done "the right way" while developing submodules for a project.

@chrisirhc

This comment has been minimized.

Copy link
Contributor

chrisirhc commented Jun 30, 2015

There are two ways to differentiate the modules to be imported:

  • string argument you provide to require()
    For example: require('a') vs require('b') or require('./a') vs require('../a')
  • The source contents of the module code

I think the crux of this problem is that browserify isn't aware of the real path of the module (after traversing all symlinks).
Perhaps browserify should call realPath on the path returned from the resolves to determine if they're the same file?

@chrisirhc

This comment has been minimized.

Copy link
Contributor

chrisirhc commented Jun 30, 2015

I've made a PR (#1318) for getting the real path and resolving the packages via their real paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment