5

Setup:

Package models

  • Common mongoose models used across multiple apps
  • peerDependencies: "mongoose"

Package app

  • dependencies: "mongoose", "models"
  • Linked with models through app> npm link models

Issue:

When developing models, I need mongoose installed under node_modules, otherwise it can't find mongoose.

However, when using models under app, if mongoose exists under node_modules in models, it uses that copy instead of sharing the same instance of mongoose with app.

The way I'm making this work now is installing mongoose when developing models, then deleting it when using it under app. I've looked into parent-require but this seems to only solve the issue with npm link not finding the package from the parent, not the issue with having to remove/install the node_module (or am I doing this incorrectly?)

Related: Sharing a Mongoose instance between multiple NPM packages

3 Answers 3

9

I've taken to using require.main.require instead of require for modules that need a shared instance.

For example, require.main.require('mongoose') will guarantee only the top-level mongoose is used.

Sign up to request clarification or add additional context in comments.

1 Comment

For those coming here from Google, there is potential good news. Node v6 may finally include a patch for this bug..
0

In case you get an error

require.main.require is not supported by webpack

... call npm link <required module> in your module's root dir

E.g. I had the same issue with peerDependency react. So I did npm link reack for my local module and it worked.

Comments

0

Here is a module that you can use that deals with parent and grandparent modules that are linked

/**
 * the original module scope
 */
const _BASE_MODULE = module;

/**
 * the top level module (fixes nasty peer dependency issues with npm link)
 */
const _MODULE = topLevelModule();

/**
 * find topmost module scope
 */
function topLevelModule() {
    let _mod = _BASE_MODULE;

    while (_mod.parent) {
        _mod = _mod.parent;
    }

    return _mod;
}

/**
 * cheap way to check if the module is available,
 *
 * @param {string} mod module name
 * @return {boolean}
 * @todo if we need better then we should switch to browserifys resolve package, but thats heavy
 */
export function isAvailable(mod) {
    try {
        _MODULE.require.resolve(mod);

        return true;
    } catch (e) {
        return false;
    }
}

/**
 * requires a module from the top level scope
 * @param {string } mod module name
 * @return {*}
 */
export function topLevelRequire(mod) {
    return _MODULE.require(mod);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.