James Snell of IBM wrote an excellent report on the discussions at this week’s TC39 meeting concerning the integration of Node.js modules with ECMAScript 2015+ modules. You should read his report before reading the rest of this post.
After I read his report, I realized that it might be useful to clarify something that was implicit in our module discussions but which we didn’t explicitly talk much about. Open-ended support for various kinds of modules, other than just ESMs was always a goal of the ES module design and specification. To this end, most of the ES module semantics is defined in terms of a specification level abstract class named “Abstract Module Record”. The design intent was that concrete specification subclasses would be defined for various kinds of modules and that for each kind, concrete implementations of the abstract interface methods would provide module loading/linking/evaluation policies that were specific to each kind of module.
However the ES2015/2016 specs only included one concrete subclass of “Abstract Module Record”. It’s called “Source Code Module Record”, but for the purposes of this note it would be better to think of it as “ESM Module Record”. I suspect some of the early misunderstanding about general ES module requirements came from folks looking at the concrete methods of “Source Code Module Record” and assuming that its semantics were also requirement for non-ESM modules such as Node modules
I think many of the issues that we identified this week can probably be handled “simply” by defining one or more additional “Abstract Module Record” subclasses, for example a “NCJS Module Record”. Of course, every experienced software designer knows that an interface that only has one implementation is likely a buggy interface. So, we can be pretty sure that as we try to define new forms of concrete Module Records to support Node we will also discover interface level bugs in the ES specification that need to be fixed. For example I’m pretty sure that the module specifier mapping idempotency requirement should be specific to ESMs but is currently specified as being more broadly applicable.
I want to thank all Node folks for attending this TC39 meeting. I hope they found the inside of the ECMAScript sausage factory interesting and not too smelly. Hopefully, this is the beginning of regular and active participation within TC39 by the Node.js community.