-
Notifications
You must be signed in to change notification settings - Fork 44
Phase 2-3: package.json configuration #214
Comments
There is no chance that we are compatible with all those modules. For example, they use Of course, this may change in the future, but until it does, we should assume incompatibility. |
In phase 2, from what I recall, NodeJS can explicitly know whether you are importing a CJS or an ESM, because if you are using And if that is so, why would we need two fields in the And if the answer to that is "for future use", then I suggest we wait for that future (which may never come), and then decide to add this new field. |
@giltayar The type of module the consumer is asking for is definitive. But the target package may want to also support CJS consumers. Effectively a package can have multiple entrypoints and these get instantiated separately, i.e. independent identities. This has been called "dual-mode" packages. @GeoffreyBooth what is your proposed behaviour if the "nodejs" field is missing in the target package of an ESM import? I hope we can avoid a cascade. |
@giltayar there is definitely not consensus on that for longer term; i feel very strongly that only the author should ever get to decide the parse goal of a file, and never the user’s choice of consuming it. The “module” field is tainted because it has nonzero community usage; I’m quite confident we can’t use it. Making a “node” field is a decent idea, and we could bikeshed the name separately. I’m not sure we’d want to put “main” there since it already lives at the top level. |
fields for source types doesn't scale at all. what about wasm and html and etc etc etc etc |
@robpalme. Oops, my bad. Point taken (about dual-mode). And this coming from somebody who next week is giving a talk about ES modules in NodeConf, where I explicitly talk about dual-mode libraries. Ouch. :-) |
@ljharb - I wasn't saying that we should have author-decided or consumer-decided parse goals (I usually am for author-decided on weekdays, and consumer-decided on weekends :-) ). All I was saying is that given the incremental nature of our current way of thinking, we shouldn't put the cart before the horse, and that currently, we are in a consumer-decided step of our iterative process (the way we parse the js file is decided by the consumer). If I am wrong about that, I'd love to know. But this is now beside the point, as @robpalme pointed out, given that another possible need for these fields is dual-mode libraries. |
@giltayar right now we only allow esm in mjs files, so its currently entirely author decided. |
So currently Node only cares about the
I’m not sure what “fields for source types” means. One thing I forgot to mention is that I hadn’t given much/any thought to the contents of the "nodejs": {
"entrypoint": [
{"ast": "..."},
{"wasm": "..."},
{"esm": "..."},
{"commonjs": "..."}
]
} Or whatever. Again, just an example. I figure that this is something we could work out in the implementation. We could also add a |
this just seems like a really really poor design path. why do you have 30 entrypoints? why can't they all be resolved via this also seems to imply that there's some form of being able to request a module of a certain format... when would the this seems to be conflating out-of-band methods of specifying module formats with module resolution, which are two separate things. |
@GeoffreyBooth Is the user story here "I have shipped a rust library before importing WASM directly was a thing. I want to expose the compiled WASM directly for users of the latest node and an ESM wrapper that loads and compiles it manually for older node versions"? |
@jkrems That’s one, I suppose. My user story is #151, that I need to use ESM in Whatever the particular design is, using JSON to define the entry points is far more specific and scalable than |
@GeoffreyBooth the method for saying what type of file something is has to be separate from resolution anyway, because both deep imports and tooling need to be able to tell what each individual file is. |
That’s fine. You could define both in the Again, the point of this thread was just to propose a place to put metadata/configuration data that describes a package. I don’t have a proposal for a design of the |
This comment has been minimized.
This comment has been minimized.
Closing this as there has been no movement in a while, please feel free to re-open or ask me to do so if you are unable to. |
I did some research into the
package.json
"module"
field. I posted my findings here, including which popular NPM packages are already using it.My impetus for looking into this was the discussion of potentially using the
"module"
field as our way to determine the ESM entry point for packages. Basically, if we choose to use"module"
, there are 941 packages published publicly on the NPM registry that are already using the field. Only 75 of those (8%) point to filenames with an.mjs
extension, and could potentially be used with the new modules implementation as it stands today. If.js
extensions become allowed in"module"
, the share rises to 91%. Either way, I can’t tell frompackage.json
alone that these packages are compatible or not with our implementation; even if the entry point isindex.mjs
, there might very well be incompatible things inside the module such asrequire
statements orimport
statements of filenames without extensions.Using
"module"
has both pros and cons. In its favor, Node’s adoption of"module"
builds on some fairly substantial usage already in the community. If Node’s final ESM implementation is compatible or mostly compatible with the packages already using"module"
, that will presumably help speed adoption of ESM across the Node ecosystem. On the flip side, if Node’s ESM implementation is incompatible with many of the packages already using"module"
, there could be pain for users as they try toimport
some of these packages (including some very popular ones likesinon
andredux
andvue
) and Node throws errors. Presumably the most popular packages are very actively maintained and will update their"module"
builds before too many users try to use them in native ESM mode, but there’s always the risk that the transition period will be messy.As an alternative, we could come up with a new
package.json
field, likemainModule
, that isn’t currently used (or not commonly used). But I think a better solution might be to create a newpackage.json
field callednodejs
that takes a configuration object:This namespacing frees us up from worrying about collisions with
package.json
fields already in use by the community, both now and in the future. It also gives us a place for other potential configuration options, like themimes
proposal, and follows a pattern used by other popular Node modules such as Babel and ESLint and Prettier. Node would control the specification of fields in this block, and tools like Webpack and Rollup would presumably make sure that they follow Node’s rules for things like ESM support before outputting tonodejs.module
. Adoption will be slightly slower than if we go with straight"module"
, but at least we won’t have early-but-incompatible adoption. Thoughts?cc @guybedford @jkrems @SMotaal
The text was updated successfully, but these errors were encountered: