You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Sep 2, 2023. It is now read-only.
Repository navigation
This repository was archived by the owner on Sep 2, 2023. It is now read-only.
Feature: Import CommonJS without needing asynchronous syntax #116
eval(fs.readFileSync('./underscore.min.js'));// Creates `_` variable in global scopeconsole.log(`Using Underscore version ${_.VERSION}`);
This can also be written as:
const_=require('underscore');// CommonJS moduleconsole.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.
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.
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.
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?
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.
@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.
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.
@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.
@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:
Activity
devsnek commentedon May 20, 2018
once again... use of static import syntax doesn't infer the handling is happening synchronously...
benjamingr commentedon May 20, 2018
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 commentedon 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 commentedon 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 commentedon May 21, 2018
@GeoffreyBooth would it be possible to phrase the issue to reflect that if you agree?
GeoffreyBooth commentedon 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.
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 commentedon 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 commentedon May 23, 2018
From this:
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).
In essence, the original CJS module system has been operating synchronously, however
import('…')andimport … from '…'predicate that the loaded resource be asynchronously loaded and hence promise-wrapping the namespaces (even if they are synchronously loadable CJS modules) whereasrequire('…')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 commentedon May 23, 2018
@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 commentedon May 23, 2018
@GeoffreyBooth I would say that my main confusion is around the term
asynchronous syntax, since theasynchronousbit is more about the required behavior to access something, but some workflows likePromiseare 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: