4 ms·
Right. In other words, if you `import` a file with that line, it should crash. If you `require` the file, it will do nothing. The context can determine the file
by s_tec 8y ago
Right. In other words, if you `import` a file with that line, it should crash. If you `require` the file, it will do nothing. The context can determine the file type unambiguously, and you don't need an extension.
> This was discussed, but one of our goals is to be able to know what type of file something is before reading its contents.
The file extension came from an earlier plan where `require` and `import` could be used on both types of Javascript. Now that the plan uses `import` only for modules and `require` only for scripts, you can get rid of the extension.
> our ESM implementation, unlike CJS, doesn't assume that everything it uses comes from the local fs.
Node is `import`ing from HTTP, it can use content-type like browsers do. This is only a problem for local file systems, which don't have content-type. For that, you can just assume everything is a module. If people need to load CJS, they can use `require` (as the proposal above already says).
Bare import specifiers like `import { foo } from 'lodash'` aren't URI's, so you don't need to maintain compatibility with the browser. For this, you can just use the existing [package.json/module](https://github.com/rollup/rollup/wiki/pkg.module https://github.com/rollup/rollup/wiki/pkg.module) field to determine whether to enter the ESM world or the CJS world.
I know Node rejected the package.json solution back when they were trying to make `import` and `require` interchangeable, but now that they aren't, I think the original performance worries should no longer apply.
- snek 8y ago>In other words, if you `import` a file with that line, it should crash. If you `require` the file, it will do nothing This is the situation we don't want to be in, where the consumer is choosing. The consumer doesn't know. Even if you, a human, read the file, you don't know what the author's intention was. > you can just use the existing pkg.module field to determine whether to enter the ESM world or the CJS world. We really can't though, because its already full of files that are intended to be used with rollup/babel/etc, which have incomplete implementations of esm.
- Touche 8y agoI disagree. Knowing what format a module is written in is no different than knowing it's API. You can't blindly start using a module without knowing stuff about it and how it's intended to be used
- snek 8y agoNode disagrees. You can `require('./a')` without knowing if its `a.json` or `a.js` or `a.node`. All you need to know about `./a` is the interface it exposes.
- s_tec 8y ago> This is the situation we don't want to be in, where the consumer is choosing. The consumer doesn't know. Even if you, a human, read the file, you don't know what the author's intention was. If I am importing a file URI, then I am the author, and I know what it is. File URI's are primarily used for linking together stuff in the same git tree. If I am using third-party code, it will be a bare module import specifier from node_modules, not a file URI. I agree that there are weird situations where this isn't the case, but you don't need to worry about those. Why? Because module support in Node is a new feature, and therefore opt-in. The people who choose to opt-in know what they are doing, and are probably running a pure ESM codebase already. The goal should be to make something useful to the 99%, and let the other 1% keep doing it the old way. If you are already using Rollup, then this will be plug & play. Rollup already assumes that everything you `import` is a module, and puts them in strict mode. > We really can't though, because its already full of files that are intended to be used with rollup/babel/etc, which have incomplete implementations of esm. That's a legitimate concern. Even if using "module" itself is too risky, but the approach itself seems solid. If I want to publish something to NPM that supports native ESM in Node, it's easy for me to add something to package.json that indicates my support, without renaming all my files. My packages on NPM have both CJS and ESM entry points. The ESM entry point is for tools like Webpack & Rollup, which do not understand the .mjs extension. I tried using the .mjs file extension for this, and it just broke things. There is no way we can re-write every Webpack and Rollup config file in existence to be compatible with this.
- snek 8y agoEven in the same project, you might have multiple people working. The specifics end up not mattering, because the goal here is to always be unambiguous by default. If you want to have your own setup in your project, you can use a loader resolve hook and come up with your own rules. Assuming that everything you import is esm is doable, but we want cjs to continue being a first-ish-class citizen, since so much code uses it. Right now you can opt into a dual mode package by having a file.js and a file.mjs and setting main to `./file` without an extension, and it will "just work". You can also have index.js and index.mjs without a main field in package.json.
- 8y ago