12 ms·
I wonder why they kept the ugly .mjs extension. This is a hold-over from an earlier plan, and doesn't seem necessary in this iteration. This new plan seem to b
by s_tec 8y ago
I wonder why they kept the ugly .mjs extension. This is a hold-over from an earlier plan, and doesn't seem necessary in this iteration.
This new plan seem to be going down the path that `import` is for modules while `require` is for everything else. If that's true, then they shouldn't need a special file extension for modules - it should always be clear from the context which is which.
The only exceptions I can think of are executable scripts (which could use a command-line option) and packages in node_modules (which can use a special package.json field).
- Klathmon 8y agoIf it's not needed, then I'm also questioning it. Requiring that extension breaks a lot of previously "very nice" things. Being able to create a file like `thing.js` and require it by doing `require('./thing')` made it easy to be able to switch that out with a directory later and put an `index.js` in there without having to change any import statements. That is something i've used countless times and it tends to really improve my development experience since modules can grow more naturally and it avoids lots of one-file directories, and with the `.mjs` it's entirely gone.
- treve 8y agoThe .mjs extension isn't required in browsers, but absolute paths are. So even if the .mjs extension requirement is dropped, I don't think the implication is that './foo' can successfully resolve to './foo/index.js' as there is no such thing as a directory in HTTP and you don't want browsers to make multiple guesses for which path exactly exists.
- mstade 8y agoIsn't the absolute path (not exactly true, since dots are supported) thing just a matter of punting till later? If I recall correctly, they couldn't agree on resolution rules and perhaps more specifically how node-like rules would translate to the web, so they punted and went for an "absolute or bust" kind of approach till someone comes up with a better idea rather than painting everyone into a corner. Mapping identifiers and path resolving functions have been suggested as ways to make identifiers "nicer" I think. This seems reasonable. I reckon the reason why node's behind on figuring out how to make ESM work is because of all this implicit loading magic, and a reluctance to break existing code. (A commendable goal I think.)
- repsilat 8y ago> you don't want browsers to make multiple guesses The webserver does that work.
- jkrems 8y agoBut that would mean that every single webserver would have to implement that logic. Consistently.
- snek 8y agoExcept no? Only servers where stuff making requests expects the server to behave that way. The interesting thing about this is that every server in the world already works like this: they expect the person calling the server to know how the server works.
- Klathmon 8y agoYou know what, I had completely forgotten about that, and it completely changed my view. Sure, we can have webservers serve up different thing based on parsing the url (a GET for `/users` could return `/users/index.mjs` if it wants), but having that required by the spec would be a mess, and not having it in the spec but still allowing it in node would cause annoying bugs when trying to use a library on both sides.
- JimDabell 8y agoThis is a pretty ubiquitous web server behaviour already. If you link to /foo and it happens to be a directory, the server redirects you to /foo/. It then looks within the corresponding directory for an index file and serves that. Most web servers have this as the default configuration, but the default list of potential index files doesn't include index.js (it's usually just index.html or index.html index.htm default.htm etc). It's usually a one line change to include index.js. This has worked fine for decades; there's no need for including this in the JavaScript spec. – it's up to whoever wants their server to respond that way to configure it appropriately.
- Klathmon 8y agoBut if node.js were to use a different default of how to do filesystem lookups (look for foo.js, then fallback to foo/index.js if not found), then you'd start seeing modules which wouldn't work on the web without the web server setup to use that exact same system. That's now an implicit contract. This is in all honesty a small problem in the grand scheme of things, and it's one that can be equally solved by better editor tooling (for auto-refactor filenames abilities that also change all imports, since imports are for the most part statically analyzable now)
- JimDabell 8y ago> But if node.js were to use a different default of how to do filesystem lookups (look for foo.js, then fallback to foo/index.js if not found) They won't do that because they are clearly intent on having code work between environments. They repeatedly tell people this whenever people complain about .mjs. So we can discount this as a possibility. > you'd start seeing modules which wouldn't work on the web without the web server setup to use that exact same system. That's now an implicit contract. The inverse is true for their .mjs solution, which is essentially "Use Node's .mjs on the web or shared code will break in Node". This requires adopting the Node naming convention on the web and altering web servers to serve .mjs files as application/javascript. The .mjs file extension isn't a standard and doesn't make sense on the web; ESM modules are both of those things. If you think changing web server configurations for an implicit contract is not acceptable, you should be against .mjs.
- snek 8y agoIt isn't required when importing something, its required for the filename. You can continue to do `import './thing'` where you have `thing.mjs`.
- Klathmon 8y agoThat's not what the linked article says, and even if it is true, it still won't do a lookup for `index.mjs` inside the `thing` folder, so it still hurts that usecase.
- FactolSarin 8y agoThey say that it's required for ecsmascript modules that neither import nor export (for instance, modules that place things in the global namespace), but I would argue those are mostly shims for a pre-moudule era and they should just be `required()`. Or perhaps they could use some special comment at the top to let Node know it should be treated as a module even though it doesn't look like one. Otherwise, just work down the `import` tree from index.js and anything that is imported is a escmascript module, everything that is required() isn't. Of course, this is just an armchair quarterback opinion, but I'm curious to know why that approach wouldn't work.
- s_tec 8y agoExactly! You have to know whether something is a script or a module before you can parse it, but with this plan, that's always clear from the context. This is exactly how browsers do it, by the way. If you `import` something, is a module, period. The `<script>` tag is the only place that supports both, so they use a `module="true"` flag to indicate which is which.
- deleted 8y ago[deleted]
- chrismorgan 8y agoSmall correction: it’s <script type="module">, as distinct from <script> or <script type="text/javascript">.
- jkrems 8y ago> This is exactly how browsers do it, by the way. If you `import` something, is a module, period. The `<script>` tag is the only place that supports both, so they use a `module="true"` flag to indicate which is which. This is not entirely true. If you import something and it's served with a content type associated with JavaScript modules, then it's interpreted as a JS module. But if they are served with a wasm content-type, they may in the future interpreted as wasm modules. In node there's the additional content-type of "CommonJS file" which has to be handled somehow as well. Non-module script tags aren't really relevant because node itself never supported scripts (at least not what the browser and the ECMA standard calls scripts).
- wakamoleguy 8y agoIt sounds to me like it is a temporary holdover from the earlier plan to speed up the implementation of Phase 1. The idea is that it's better not to add the complexity to parsing while the minimal kernel is figured out, and then layer it on in Phase 2 once the most important bits are working. I do find it a little annoying personally, and it will hurt my personal adoption slightly...but I understand why they would tackle it in that order.