简体   繁体   中英

Return destructured object from IIFE in ES6 module

I can't figure out how to essentially do this at the end here

export {inMemoryDb, backup };

So I want to export the returned value from the IIFE basically as named exports.

InMemoryDB.ts

const result = (async () => {
  const inMemoryDb = newDb();
  await inMemoryDb.public.migrate();
  const backup = inMemoryDb.backup();

  return { inMemoryDb, backup };
})();

export result; 
// but I actually want to export it as { inMemoryDb, backup }

I think it should be

const result = (() => {
    const inMemoryDb = newDb();
    inMemoryDb.public.migrate()
    const backup = inMemoryDb.backup();

    return { inMemoryDb, backup };
}());  //<-- note here.

then

export const inMemoryDb = result.inMemoryDb;
export const backup = result.backup

All exports have to be static. That allows many opimisations in the module resolution. Because of that, even if you have an object, you can't export its properties as named exports without explicitly specifying them.


However, the main problem of your code is asynchrony. That's what prevents you from just exporting those things as-is, and causes complexities importing it.

Solution options:

  1. The Top-level await proposal (Stage 3)

    If you use a platform that supports it, transpile your code using a tool like Babel , or use TypeScript 3.8 or later, then you can already use this feature.

    It lets you trash the IIAFE, so you can simply write:

     export const inMemoryDb = newDb(); await inMemoryDb.public.migrate(); export const backup = inMemoryDb.backup();

    The best thing about this is that you don't even have to await it when you import it, it's done automatically.

    This is the solution to this problem, but for those who don't have access to this feature yet, here are some workarounds:

  2. Exporting everything in a Promise

    Well, that doesn't answer your question, as it doesn't use named exports. By the way, that's almost what your code does!

     const result = (async () => { const inMemoryDb = newDb(); await inMemoryDb.public.migrate(); const backup = inMemoryDb.backup(); return { inMemoryDb, backup }; })(); export default result;

    For this to work, your importer will need to:

     import result from './inMemoryDB.ts' (async () => { const { inMemoryDb, backup } = await result // Do stuff })()
  3. Exporting everything in separate promises

     const result = (async () => { const inMemoryDb = newDb(); await inMemoryDb.public.migrate(); const backup = inMemoryDb.backup(); return { inMemoryDb, backup }; })(); export const inMemoryDb = result.then(({inMemoryDb}) => inMemoryDb); export const backup = result.then(({backup}) => backup);

    Importer code:

     import { inMemoryDb, backup } from './inMemoryDB.ts' (async () => { const foo = await inMemoryDb const bar = await backup // Do stuff })()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM