I meant transforming CommonJS module code to ES6 modules litterally, sort of a BabelJS transpiler…
Nicolas Froidure

ah, that form is not possible since the shape of the module needs to be known ahead of time.

In particular, you cannot add keys to exports like in your example. It would need to compile to something like:

import {require} from 'node:commonjs'; // bikeshed
export let foo;
export let bar;
{ // block statement
  function _foo() { // shadows outer, needed to be renamed
return 'bar';
  function _bar() { // renamed as well
return 'foo';
  foo = _foo;
bar = _bar;
} // end block statement

But this doesn’t work for all CJS:

with (Math) { // Modules are strict
// this one at least doesn't parse
exports.sin = sin;
function f(x) {
x = x || 1;
return g.apply(arguments); // this changes behavior in strict
exports[computed_at_runtime] = 0; // unknown name at compile time
this.foo = 1; // this is `undefined` in Modules
await = 1; // await is reserved in Modules
require('foo') // can't translate require to import
// require isn't idempotent
delete require.cache[require.resolve('foo')]
module.parent // parallel loading in ESM means .parent doesn't map
... there are more ...