javascriptecmascript-6es6-modulesdestructuring

Why does choosing module imports not work like destructuring?


I have a file that is similar to this:

const COLORS = {
  PRIMARY_COLOR: 'red',
  SECONDARY_COLOR: 'green'
};

const APP = {
  APP_COLOR: GRAY_DARK,
  APP_FONT_SIZE: FONT_SIZE_NORMAL,
  APP_FONT_WEIGHT: FONT_WEIGHT_NORMAL,
  APP_SEPARATOR_COLOR: GRAY_LIGHT
};

export default {
  ...COLORS,
  ...APP
};

The issue is when I'm trying to destructure that object from another file, I get undefined values?

import theme, { PRIMARY_COLOR } from '../../../themes/default';

printing the theme object works fine but printing PRIMARY_COLOR gets undefined

Any help?


Solution

  • To understand the difference, you first need to know the way they are exported.

    In case of React, the export goes something like this

    const Component = ...
    ...
    ...
    export Component;
    

    This becomes available under React.Component and you can import it like import { Component } from 'react';

    The way these look under the microscope is:

    default.Component
    ...
    

    While everything else is just under the default object.

    If you do a quick console.log of theme, you'll understand what I mean.

    I hope this makes sense.


    Let's go a little in depth.

    Suppose you have the following bit of code:

    const a = {
        test: 'hello',
    };
    
    const b = {
        foo: 'bar',
    }
    
    export default a;
    

    Now, let's import that

    import * as theme from './test.js'
    

    When we do a console.log( theme ) we get

    { default: { test: 'hello' } }
    

    What does this show? It means that the export object of a file contains a default property which is automatically loaded into memory when we do something like import theme from 'test'. However, if you have more than one export, the compiler gives you the option to pick and choose, but at the same time, provides you with a default object just for fall back.

    In your case, you have exported everything under the default. When you do import theme from './theme' all works fine. However, when you do { PRIMARY_COLOR }... it tries to find something which was exported like

    export PRIMARY_COLOR...
    

    I hope this makes it clear! :)