disambiguate "web compatibility" #142
Description
similar to "transparent" interop, the use of the term "web compatibility" is a bit muddy in usage.
I think we need to discern 2 main things:
- Code compatibility concerns: if users are being encouraged to/must produce code that cannot run on web browsers. Examples include:
- using things that are not present on
import.meta
in browsers - using magic variables like
__filename
which are not going to be present in the browser - using modules written in CJS
- using things that are not present on
- Platform compatibility concerns: if the Node implementation of ESM varies from the WHATWG implementation in a way that prevent people from shipping an ESM module graph that works in Node to the web. Examples include:
- having a different cache mechanism for indirection
- having a different value for
import.meta.url
- having a different resolution algorithm
I want to be very clear that platform concerns are about how ESM graphs are loaded and what contextual data is provided to those modules. Underlying formats used to ship modules is unaffected and may be overloaded through different container mechanism such as using webpackage or BinaryAST.
Notably, I would like to make a discerning line about if importing non-ESM is a compatibility concern on the Code level or the Platform level.
I believe very firmly that importing non-ESM is neither.
-
For the Code compatibility concern, the simplest example of this is to show an application that contains only ESM. The Code compatibility concern is about requiring code be written using syntax or APIs that cannot work on the web. If you don't import CJS, you don't have this compatibility concern, even if the feature of importing CJS exists.
-
For the Platform compatibility concern, people can claim that
import 'foo';
resolving to CJS in Node is a platform compatibility concern. I want to claim this is a false concern.- Having
foo
resolve to ESM is still possible either by porting, bundling, or shipping multiple builds. At no point isfoo
required to be CJS by writingimport 'foo';
. - If we look at the idea of the web shipping a format that Node does not support (such as HTML modules). There is nothing preventing that author of HTML modules to take the inverse approach so that it could be loaded in Node. If we are to state that importing CJS is a platform compatibility concern due to requiring specific dependencies be written in CJS, we would also need to state the inverse for HTML modules ; which is false, as
import
does not require the format of the dependency being loaded to be anything , be it CJS or HTML.
- Having
I will leave migration concerns up to @demurgos 's incoming review of the issue, but felt that we should address the topic of what "web compatibility" is in a way that we can be concrete in what breaks when we talk about features.
I am open to changing definitions above, but want to make us be more mindful of using the term "web compatibility" without explaining what breaks by including a feature. Is it the ability to use ESM loading mechanisms in both places, or is it the ability to run the same source text in both places? We should also seek to prioritize if the ability to run the same source text in both places is mandatory given that any usage of CJS will not be possible to run without some assistance in the browser.