Description
Here's what we're doing to support ESM in AVA. The work has already been broken up into individual issues that you can work on. See the ESM support project for details.
See https://nodejs.org/docs/latest/api/esm.html for the latest on what Node.js is implementing (this issue was opened when that documentation was for Node.js 13.1.0). I'm expecting this to become available without a flag at some point.
-
Firstly, we're moving AVA's Babel support into a separate package that you can install alongside AVA. This will reduce confusion as to what module format AVA supports out of the box. It also allows us to evolve that package independently, which is important since loader hooks may still take some while to land.
-
Secondly, we'll be detecting test files with
cjs
andmjs
extensions. Currently, by default, we only look for files withjs
extensions. -
When loading test files, we'll always load files with
cjs
extensions usingrequire()
. Files withmjs
extensions will be loaded usingimport()
. Support loading .mjs test files #2344 -
Note that
import()
itself is currently behind an experimental flag. Allow Node arguments to be configured #2272 will let you configure that flag. We'll print a useful error message ifimport()
is not available and AVA is trying to load anmjs
test file. -
When it comes to
js
files we'll follow thepackage.json
"type"
field. So by default we'll treat them as CJS. -
We'll also let you configure how
js
files (and other files, but notcjs
ormjs
files) should be loaded. This way you could override the"type"
field, or load test files as ESM even if you're publishing CJS. Add configuration to specify how extensions should be loaded #2345 -
The Babel provider will detect when you've configured files to be loaded as ESM even though it cannot load them as such, and print an error.
-
We'll support
ava.config.cjs
andava.config.mjs
configuration files. However deciding what to do withava.config.js
files is more difficult. We shouldn't change how it's loaded based on"type"
fields, nor can we use the built-inimport()
since it needs to be enabled. And finally, right now we need to be able to load it synchronously for use with our ESLint plugin. Support ava.config.mjs files #2346 -
I'm proposing we remove support for
import
statements andrequire()
calls fromava.config.js
files. In other words, they must only containexport default {}
orexport default () => ({})
style configurations. This is a breaking change, as at the moment we loadava.config.js
using theesm
package. However it gives us the best upgrade path. -
We do need to consider what syntax we use in our documentation. I think we should use CJS, until ESM is available without a flag. It's not as hip, but at least it'll work out of the box.
-
When loading
require
modules, if they are loaded from the project itself we can use the above logic to load the files based on their extension. If they're packages andimport()
is available then that should work. Else, for now, we'll fall back to usingrequire()
. Update our handling of therequire
option to support ESM dependencies #2347 -
Dependency tracking for our watch mode also needs work. Make dependency tracking work with ESM imports #2388