defense-of-dot-js icon indicating copy to clipboard operation
defense-of-dot-js copied to clipboard

Prioritize index.js before module.js

Open pitaj opened this issue 8 years ago • 7 comments

The defined behavior of using module.js as a stand-in for a module field in package.json is problematic. Consider the following case:

  • A package exists where there is no main or module field defined in package.json
  • This package does not use standard module syntax
  • This package has two files in the root directory:
    • index.js
    • module.js
  • A require or import is run on this module

According to your resolution rules, as I understand them, Node would attempt to parse this module as a standard ES module. However, if this module is indeed not coded with the standard ES module syntax, this require will fail.

That is backwards-incompatible behavior. I suggest that module.js is only interpreted as a module field in package.json if:

  • main field is undefined
  • module field in undefined
  • No index.js file exists in the root directory of the package

pitaj avatar Apr 27 '16 23:04 pitaj

Yeah, we were hesitated to add that note there. It is true that we might not be able to do so. Initial analysis of existing npm pkgs suggested the following:

  • from 116k "latest packages" analyzed, module.js exists only in 127 of them, and it is set as main in 37 of them.

Other alternatives were:

  • from 116k "latest packages" analyzed, default.js exists only in 11 of them, and it is set as main in none of them.
  • from 116k "latest packages" analyzed, mod.js exists only in 10 of them, and it is set as main in 6 of them.

Ultimate, we will have to make a decision on this. If the decision is that "module" is required in package.json, no more magic, then we will be safe, that's the safer option. But if we want to have parity with existing capabilities, we will have to choose a name that makes sense, and it might affect few users/packages.

caridy avatar Apr 28 '16 14:04 caridy

In my opinion, making the module field required is the best option, as ideally that field should be defined in every module anyways.

pitaj avatar Apr 28 '16 16:04 pitaj

I agree with you. And in fact part of the stats that we have gather, is aligned with your thoughts, considering that 85% of those 116k "latest packages" analyzed, have an explicit "main" entry in package.json, and in half of them, the value is set to the default "index.js". But one of the counter arguments for this in a previous discussion was the fact that people can have a pkg without explicitly calling the value of "main". I think this is TBD, if we get node to reconsider their decision, and go with this proposal, we can drill down on this topic and make a final decision.

caridy avatar Apr 28 '16 16:04 caridy

In that case, you may want to at least for now remove that part of the proposal so it does not give a bad first impression. It can always be added back later.

pitaj avatar Apr 28 '16 16:04 pitaj

/cc @dherman, @wycats what do you guys think?

caridy avatar Apr 28 '16 17:04 caridy

Or better yet because it is a good idea to make writing packages easier and would impact only ~100 packages, you could mark it as optional and state concerns about it rather than just delete it.

qraynaud avatar Jun 25 '16 12:06 qraynaud

If the decision is that "module" is required in package.json, no more magic, then we will be safe, that's the safer option.

Yeah I think this is the best course of action without reading the files. It will also kind of "force" package maintainers who want to distribute ES2015 code to actually pay attention to their package.json.

pitaj avatar Jun 25 '16 12:06 pitaj