ext
ext

Reputation: 2903

ESM export * except from module

Given I have two imports with lots of named exports (too many to write them all out) and I want to reexport these except a few of them. In my case this is because a few exports collide.

As an example of what I want to archive lets assume we have two files:

foo.js:

export const a = 1;
export const b = 2;

bar.js:

export const b = 1;
export const c = 3;

If I want to aggregate and reexport them all using CommonJS I could do something like this:

/* use rest destructuring to put everything except "b" into variable "foo" */
const { b, ...foo } = require("./foo"); 
const bar = require("./bar");

module.exports = {
    ...foo,
    ...bar
};

As I'm using typescript the closest I've gotten is using export = { ... } in a similar way:

import * as foo from "./foo";
import * as bar from "./bar";

const { b, ...foo2 } = foo;

export = {
    ...foo2,
    ...bar,
};

However it is my understanding this will create a file with CommonJS module.exports instead of a proper ESM module (and probably require esModuleInterop). And it is a typescript construct and not available when writing vanilla JS.

Is there a way to archive this using ESM import / export instead?

Upvotes: 8

Views: 5846

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074276

Is there a way to archive this using ESM import / export instead?

No, not in pure standard ESM, not without doing what you're trying to avoid: Listing the named exports. There's no "rest" concept in ESM import/export.

I think you know this, but you could export an object with properties for a, b, and c, but that's a very different thing from re-exporting named exports. It wouldn't be a live binding, and the syntax for importing its parts is different from importing named exports (unless build-time tools like TypeScript or bundlers, etc. are involved).

Just FWIW, here's what that looks like (it's very similar to your TypeScript version near the end), but I don't think it's what you want:

reexport.js:

import * as foo from "./foo.js";
import * as bar from "./bar.js";

const { b, ...restOfFoo } = foo;
export default {
    ...restOfFoo,
    ...bar,
};

Then using it is:

// Import the object (which is the default export)
import stuff from "./reexport.js";

// Destructure into local vars (optional, but...)
const { a, b, c } = stuff;

// Use it...
console.log(a, b, c);

That's all standard ESM.

Upvotes: 3

Related Questions