Skip to content
This repository has been archived by the owner on Sep 2, 2023. It is now read-only.

Feature: Import CommonJS without needing asynchronous syntax #116

Closed
GeoffreyBooth opened this issue May 20, 2018 · 10 comments
Closed

Feature: Import CommonJS without needing asynchronous syntax #116

GeoffreyBooth opened this issue May 20, 2018 · 10 comments
Labels

Comments

@GeoffreyBooth
Copy link
Member

GeoffreyBooth commented May 20, 2018

Split off from #114:

Updated feature request description:

Imagine code like this in current Node:

eval(fs.readFileSync('./underscore.min.js')); // Creates `_` variable in global scope
console.log(`Using Underscore version ${_.VERSION}`);

This can also be written as:

const _ = require('underscore'); // CommonJS module
console.log(`Using Underscore version ${_.VERSION}`);

Both of these examples are written without asynchronous syntax on the user’s part: there are no callbacks, no promises, no await. Perhaps Node is doing asynchronous stuff behind the scenes, but the user is unaware of it. require appears to be as synchronous as readFileSync.

This feature request is that a user’s code to import CommonJS modules via ESM should be like these examples: no callbacks, no promises, no await. This feature request doesn’t concern Node’s implementation under the hood, and whether it is synchronous or asynchronous; the request is only that the user’s code be able to be written in a synchronous style.

Use case 48. Part of #100.


Original feature request description:

ESM imports of CommonJS can be written in a synchronous style:

import { keys } from 'underscore'; // CommonJS package
const dateKeys = keys(Date);

The point of this feature is that users can use the same synchronous style of coding (in the vein of fs.readFileSync as opposed to callback- or promise-based alternatives) when the import is of CommonJS. Or put another way, users aren’t required to use await or promises or other asynchronous constructs in code in order to import CommonJS.

Use case 48. Part of #100.

@devsnek
Copy link
Member

devsnek commented May 20, 2018

once again... use of static import syntax doesn't infer the handling is happening synchronously...

@benjamingr
Copy link
Member

Note that this feature request isn't asking for imports to work here (like they do in Node.js today) - you're asking for named exports.

@ljharb
Copy link
Member

ljharb commented May 21, 2018

Not necessarily; this seems like it’s asking for importing CJS to not always produce a promise - the named import syntax is simply a distraction from this issue.

@devsnek
Copy link
Member

devsnek commented May 21, 2018

the commonjs system is entirely synchronous so i'm not sure how one would conclude that a promise would be required to use it

@benjamingr
Copy link
Member

Not necessarily; this seems like it’s asking for importing CJS to not always produce a promise - the named import syntax is simply a distraction from this issue.

@GeoffreyBooth would it be possible to phrase the issue to reflect that if you agree?

@GeoffreyBooth
Copy link
Member Author

GeoffreyBooth commented May 22, 2018

Yes, I agree. Once we settle on good wording for #114 I’ll update this one, unless you think we no longer need this issue.

the commonjs system is entirely synchronous so i’m not sure how one would conclude that a promise would be required to use it

In an all-CommonJS environment, sure. This issue refers to importing CommonJS into ESM. As I wrote in #114, during the last meeting someone suggested CommonJS would be imported via import() which would return a promise. This feature request is to ask that that not be the solution, but an “appears to be synchronous” solution be chosen instead.

@bmeck
Copy link
Member

bmeck commented May 23, 2018

@GeoffreyBooth I think we can rephrase it as "CJS can be imported statically" if that makes sense. The syntax being used is untimed but appears to fit your criteria.

@SMotaal
Copy link

SMotaal commented May 23, 2018

From this:

CJS can be imported statically

While CJS is "entirely synchronous" it is designed to be imported dynamically (to use the same phrasing), that is it must be executed in order for exported bindings to be determined.

If the aim is to have CJS "imported statically" then the exported bindings will need to be "statically analyzed" without actually executing the code (@bmeck I recall some earlier efforts for opt-in declarative exports via directives).

this seems like it’s asking for importing CJS to not always produce a promise

import() which would return a promise

In essence, the original CJS module system has been operating synchronously, however import('…') and import … from '…' predicate that the loaded resource be asynchronously loaded and hence promise-wrapping the namespaces (even if they are synchronously loadable CJS modules) whereas require('…') synchronously returns the namespace for CJS and cannot do the same for ES modules.

I feel that there is a lot of room for assumptions when using those terms that might require a refinement of terminologies step, like creating a "Stipulative Definitions.md" or just "Terminology.md" something for the group.

@GeoffreyBooth
Copy link
Member Author

@bmeck I updated the description along the lines of #114. Would you still say that this request is equivalent to “CJS can be imported statically”? If so, why? I’m not sure I understand static imports if that term can be applied to this.

@bmeck
Copy link
Member

bmeck commented May 23, 2018

@GeoffreyBooth I would say that my main confusion is around the term asynchronous syntax, since the asynchronous bit is more about the required behavior to access something, but some workflows like Promise are not syntax. The feature request is still about being able to use static imports instead of requiring extra glue in order to unwrap the bindings. My presumption is that this feature would still be the same even if it was synchronous in runtime behavior. For example, I think if we had to call a synchronous API .unwrap() to get values of bindings it would fall under the same intended feature:

import {x} from 'y';
console.log('x is', x.unwrap());

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

6 participants