Skip to content
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
esamattis opened this issue Jan 9, 2015 · 12 comments · Fixed by #1318
Closed

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

esamattis opened this issue Jan 9, 2015 · 12 comments · Fixed by #1318

Comments

@esamattis
Copy link
Contributor

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

@esamattis
Copy link
Contributor Author

This commit breaks the example code 3249915

@esamattis
Copy link
Contributor Author

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

@esamattis esamattis 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
Copy link
Member

ashaffer commented Jan 9, 2015

+1

@feross
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
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
Copy link
Contributor

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
Copy link

+1

@chrisirhc
Copy link
Contributor

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
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
Copy link

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
Copy link
Contributor

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
Copy link
Contributor

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

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

9 participants