DEV Community

Cover image for Picking apart JavaScript import Syntax

Picking apart JavaScript import Syntax

Mike Bifulco on April 17, 2019

Note: this is a follow-up to my first post on destructuring. Import syntax uses destructuring pretty liberally, and it can be really confusing for...
Collapse
 
vramana profile image
Ramana Venkata

If you're asking yourself "Well couldn't we also access useState as a child of React"? The answer is - well, actually, yeah!

Well not actually if I understand correctly. The correct way to do it will be

import * as React from 'react';

What you wrote works because of bundlers exporting Module as object. But it's not really an object. I don't know the full details.

Consider this code.

export function useState() {
   console.log('useState')
}

export function useState2() {
   console.log('not useState')
}

const React = {
  useState: useState2
};

export default React;

If your import is import React from 'react' and you used React.useState, what would you expect to be logged in the console? This is the best example I can think of.

Collapse
 
irreverentmike profile image
Mike Bifulco • Edited

That's a perfect example, and a great explanation. I think a more thorough explanation is probably due in my post.

Curiosity got the best of me, and I set up a minimal example of what I mentioned in the post... and it turns out it works!

πŸ€” To be honest, the more I think about it, the more confused I am. If you dig into react's source, you can see useState is exported just like your example above, with useState a child of the object that is exported by default. I wonder if there's not also a separate export for useState, too?

Collapse
 
vramana profile image
Ramana Venkata • Edited

Ah! I did not look at React's source. So my argument is wrong as well.

My general point is that you should not use non-default exports from the default export. This may mislead your readers.

import * from React from 'react' would be correct way to do it. But react does not individual exports so it does not apply.

One reason why React may be using default export object is because babel transpiles JSX to React.createElement('div', ...) calls. If the default export is not an object, then we would have write

import { createElement } from 'react'

React team may have felt it's better to write import React from 'react' instead.

Collapse
 
ben profile image
Ben Halpern

Really nice post

Collapse
 
irreverentmike profile image
Mike Bifulco

Thank you, Ben!

Collapse
 
jplindstrom profile image
Johan Lindstrom

Can someone explain what the @ in '@material-ui' is please?

Collapse
 
irreverentmike profile image
Mike Bifulco

Hi Johan - the @ denotes an npm organization.

Collapse
 
gohawks profile image
Chu Xu

Nice post, thanks!