global-npm icon indicating copy to clipboard operation
global-npm copied to clipboard

Issues where NPM@8 needs instanciating

Open hash-bang opened this issue 3 years ago • 2 comments

There is an issue where exported npm module is a class which needs instantiating before it can be used with [email protected].

Below is a quick-and-dirty patch here where passing in the instanciate=true prop to your loader function correctly creates a singleton instance which is valid.

module.exports = (function requireNPM (npmPath, instanciate) {
  GLOBAL_NPM_PATH = npmPath
  try {
    var npm = require(npmPath)
    if (instanciate) npm = new npm();
    if (npm && Object.keys(npm).length) {
      return npm
    }
  } catch (e) {
    if (e.message.indexOf('The programmatic API was removed') >= 0) {
      // for npm >= 8. Maybe programmatic api via require('npm') is no longer available
      // https://github.com/npm/cli/pull/3762
      return requireNPM(path.join(npmPath, 'lib/npm.js'), true)
    } else if (e.code !== 'MODULE_NOT_FOUND') {
      throw e
    }
  }
  throwNotFoundError()
})(GLOBAL_NPM_PATH)

I'm not certain if this is needed in all cases though since your original patch in #7 seems to imply this was already working in npm@8? If so maybe extend the catch to have a "try to instantiate this" clause if its an event emitter class return.

hash-bang avatar Dec 30 '21 00:12 hash-bang

I have tried this solution recently, but I am not sure the returned instance is expected. npm@8 has changed a lot.

dracupid avatar Dec 31 '21 06:12 dracupid

Yeah unfortunately the downstream libraries that rely on it (this one for example) all break when they change how to setup the API object.

I kinda get how they need a class instantiating to use the NPM implementation but that raises the question on how it was working with NPM@8 in your last patch?

hash-bang avatar Jan 02 '22 04:01 hash-bang