Idiomatic Revealing Module Pattern for ES6

2020-05-16 01:02发布

问题:

In the past I've used the revealing module pattern.

function myModule() {
  function foo() ...
  function bar() ...

  return { 
    foo: foo, 
    bar: bar
  };
}

With ES6, this was improved with object shorthand.

function myModule() {
  function foo() ...
  function bar() ...

  return { foo, bar };
}

Now with built-in module syntax, I'm struggling to find the preferred pattern that is most similar to the above.

Option #1 named exports

// export file
function foo() ...
function bar() ...

export { foo, bar };

// import file
import { foo, bar } from './export-file';

foo();
bar();

Option #2 default export/import with destructuring

// export file
function foo() ...
function bar() ...

export default { foo, bar };

// import file
import baz from './export-file';

const { foo, bar } = baz;

foo();
bar();

Option #3 default export/import with name spacing

// export file
function foo() ...
function bar() ...

export default { foo, bar };

//import file
import baz from './export-file';

baz.foo();
baz.bar();

I like Option #1 with the named exports for the simplicity it offers in the "destructuring" import syntax.

import { foo, bar } from './export-file';

I also want to continue to make the module's exported API explicitly defined at the bottom of the exporting file in the export object.

export { foo, bar };
// OR
export default { foo, bar };

I read all the time that default exports are preferred, and so I've been trying to find a preferred pattern that includes default exports, but I'm reluctant to adopt as it just seems more verbose with few advantages (other than the need for name-spacing, or the inclusion of both named and default exports in some cases).

Is there an idiomatic pattern for the revealing module pattern with ES6 module syntax?

回答1:

I read all the time that default exports are preferred

No, they are not. They are simpler and have shorter syntax, and might be used more often (since there are more small, single-export modules), but they are not generally preferred.

Use the right tool for the job. You already know the advantages you want.

Is there an idiomatic pattern for the revealing module pattern with ES6 module syntax?

Yes, Option #1. When you have multiple things to export, always use named exports.

You get both explicit aliasing and tree shaking from the picky syntax

import { foo, bar } from './export-file';

as well as namespaces

import * as baz from './export-file';