question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

cjs-module-analyzer doesn't find requires if they're not top-level

See original GitHub issue
const { requires } = analyzeCommonJS(`
  mime(require('./types/standard'), require('./types/other'));
  `);

requires is an empty array.

Works fine if require call statements are not arguments to a function

Attempted fix:
https://github.com/endojs/endo/commit/2703569cd663040c7cb1f3efb7b786ed1d6249d6

The change causes any require() call to produce a requires entry, which may lead to

 Cannot find file for internal module "./niematakiegonumeru" (with candidates "./niematakiegonumeru", "./niematakiegonumeru.js", "./niematakiegonumeru/index.js") in package file:///...

Which in turn could be solved with a change here: https://github.com/endojs/endo/blob/a7b42ae2388b232f7daa099495ba11f385010fd1/packages/compartment-mapper/src/import-hook.js#L160-L175 Instead of erroring out, returning a dummy static module record that throws the error when execute is called could work. That way it’d emulate cjs more closely and not fail if the require reference was not the actual require.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
shrinktofitcommented, Apr 11, 2022

#1090 does not capture the following require:

import { analyzeCommonJS } from '@endo/cjs-module-analyzer';
const info = analyzeCommonJS(`
(function(){
    require('crypto');
})();
`);
console.log(JSON.stringify(info, undefined, 2)); // All empty arrays
1reaction
naugturcommented, Feb 21, 2022

I added postponing errors to import-hook.

PR: https://github.com/endojs/endo/pull/1090


I started looking into decoupling esm and cjs specific logic.

Parsing needs to differ between esm and cjs, so it’s provided as an argument. Meanwhile figuring out local paths is following the cjs logic, as you said.

All the differences could come in from mapParsers (with a name change ofc) where instead of a parse we’d get { parse, read, errorReporter } Instead of generating candidates and looping over them, I suggest we supply a wrapped read that finds the one file and returns it, which in turn allows collapsing read and parse into one

mapParsers is aware of cjs already and all that awareness could potentially be encapsulated there. All references to actual implementation come from the very top, via parserForLanguage which we could rename slightly to something like behaviorsForLanguage

The only hole in this idea is if module specifier is not starting with . and parser may not need to be provided - there’s no way to decide on the error behavior other than forcing the caller to pass, but AFAICT there’s only one place where importHookMaker is ever called and that guarantees parser to come in.

Here’s a messy start of the refactoring as a base for discussing if the shape of import-hook.js and parse-* seems better that way https://github.com/endojs/endo/commit/b413631c1eb3ba51ecd8fe556c8158200a287272

Read more comments on GitHub >

github_iconTop Results From Across the Web

Detect require vs. import based on the entry point, not ... - GitHub
We 're not scanning the entire dependency tree to see if somewhere down the line we suddenly switch from import to require or...
Read more >
ES modules are terrible | Hacker News
The fact of the matter is no one is trying to trick the analyzer by passing variables to require, or even more mischievously...
Read more >
Node Modules at War: Why CommonJS and ES ... - Code Red
If you dive in, you'll find that top-level await isn't even the only problematic case… what do you think happens if you synchronously...
Read more >
cjs-es - npm
Hoist the require / exports statement that is not top-level. Transform dynamic imports i.e. Promise.resolve(require("foo")) -> import("foo") ...
Read more >
ECMAScript modules | Node.js v19.3.0 Documentation
See cjs -module-lexer for the exact semantics implemented. Differences between ES modules and CommonJS#. No require , exports , or module.exports #.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found