javascriptecmascript-6es6-modules

Is there a use case for exporting the same const as a named and default export?


Question

I have seen a large codebase where every file with constants looks something like this:

export const DEFAULT_ID = 0;
export const CURRENT_CODE = 'ABC123';

export default {
  DEFAULT_ID,
  CURRENT_CODE
};

They are using both a named and a default export for all constants. Then, it seems that the constants are usually simply imported as named exports:

import {CURRENT_CODE} from './whatever.consts';

Is there any use case for this practice? Usually, either a named or a default export is used, not both.

Research

I checked this question, hoping to gain some insight into why one would use them together in this manner, but I couldn’t find anything.

The closest thing I got to an answer was in this article. In the section “Why expose a symbol as both default and named exports?”, they provide a brief example of how this allows someone to use import {A, B} from './a' instead of needing to write something like import A, {B} from './a'. However, this explanation doesn’t make sense to me since the same syntax can be used if the constants are simply exported as named exports.

My Thoughts

The only reason I can think of is that this approach may provide more flexibility when importing constants. I.e., it allows using both

import {DEFAULT_ID, CURRENT_CODE} from './whatever.consts';

let id = DEFAULT_ID, code = CURRENT_CODE;

and

import INITIALIZATION_CONSTS from './whatever.consts';

let id = INITIALIZATION_CONSTS.DEFAULT_ID, code = INITIALIZATION_CONSTS.CURRENT_CODE

for importing the constants.

Is this a valid reason for using this approach? Are there any best practices implications?


Solution

  • Is there any use case for this practice?

    Not really. The only thing I can think of is backwards-compatibility, possibly related to how they are transpiling their code, if the module is a library used elsewhere.

    The only reason I can think of is that this approach can give more flexibility when it comes to importing constants.

    A default export is not necessary for that. You can easily use a namespace import with named exports only:

    import * as INITIALIZATION_CONSTS from './whatever.consts';
    
    let id = INITIALIZATION_CONSTS.DEFAULT_ID, code = INITIALIZATION_CONSTS.CURRENT_CODE