panta82
panta82

Reputation: 2721

How can I force require a non-exported file from an npm module?

You used to be able to do require('library/a/b/c.js') and it would just work.

But in newer node.js versions, there is an exports list in package.json. And if you try to require anything outside of those paths, you get error "ERR_PACKAGE_PATH_NOT_EXPORTED".

Is there a way to require those private files anyway?

(I don't need a lecture, please, just a solution)

Upvotes: 2

Views: 714

Answers (2)

panta82
panta82

Reputation: 2721

I worked out a solution like this.

  1. Add file 'patch-module.js' to project:
#!/usr/bin/env node

/* eslint-disable no-console */

const libFs = require('fs/promises');
const libPath = require('path');

Promise.resolve()
  .then(main)
  .catch(err => {
    console.error(err.stack || err);
    process.exit(1);
  });

async function main() {
  const targetFile = libPath.resolve(__dirname, '../node_modules/target_module/package.json');
  const txt = await libFs.readFile(targetFile, 'utf8');
  const pkg = JSON.parse(txt);
  delete pkg.exports;
  await libFs.writeFile(targetFile, JSON.stringify(pkg, null, 2), 'utf8');
  console.log(`Patched: ${targetFile}`);
}
  1. Add this to "package.json".
"scripts": {
    "postinstall": "./patch-module.js"
},

However, Heiko Theißen's answer is better.

Upvotes: 0

Heiko Theißen
Heiko Theißen

Reputation: 16676

If you know where the package is installed, you can still require('./node_modules/library/a/b/c.js').

But you should then not expect stability: The library might replace its use of library ./a/b/c.js with use of another library ./d/e.js.

Upvotes: 4

Related Questions