14

I am pretty new to JavaScript and have been struggling with imports recently. There has been one thing I cannot wrap my head around.

In older node modules (mostly those which came to see the light prior to ES6), which may be installed using the npm, such as express, usually no default export is defined.

My IDE (WebStorm) marks the following line with the Default export is not declared in the imported module notification.

import express from 'express';

This message may be circumvented by trying to import the whole module as an alias using

import * as express from 'express';

implicitly telling my IDE to just import everything and name it express, however doing so then leads to an express is not a function error when trying to instantiate the application on the following line.

const app = express();

Peculiarly the original import (without the alias) works.

What exactly is imported using the import statement without the alias, when no default export is defined? I would think it is the whole module, but it does not seems so.

3
  • 1
    This is more likely a problem with your IDE which does not know about how your module loader handlers pre-ES6 modules. If it works, you should use it, and either turn off the notification or find a way to declare exports of linked modules.
    – Bergi
    Commented Feb 21, 2016 at 22:54
  • @Bergi The IDE notification is not a problem also not the matter of the question. I am more interested in what gets imported as default when no such import is declared, as my IDE pointed out. I should have probably stated I am using webpack and babel with es-2015 preset to pack the modules into a bundle. I don't have time just now, but I will edit the question when I do.
    – Andy
    Commented Feb 23, 2016 at 16:54
  • @DavidPacker WebStorm stops complaining after downloading and enabling type definition files (e.g. express.d.ts) from github.com/DefinitelyTyped in Setting > Languages & Frameworks > JavaScript > Libraries > Download > express > Download and Install Commented Jun 10, 2016 at 8:36

1 Answer 1

8

What does import Module from 'module' import when no default export is defined?

Nothing. In fact, instantiating the module will throw a SyntaxError when something is imported that is not exported or exported multiple times from the imported module.

Why is it different from import * as Module?

Because import * just imports a module namespace object that has the exports as properties. If you don't export anything, it'll be an empty object.

In older, pre-ES6 node modules usually no default export is defined.

Which means that you cannot import them as an ES6 module. Your IDE seems to expect that though and puts up the warning.

So what happens if you refer to them in an import declaration? Your module loader might do anything with it, and HostResolveImportedModule will return a module record that is not an source text "ES6 module" record - i.e. it might do anything implementation-dependent with CommonJS modules.

2
  • So importing a pre-ES6 module using a ES6 syntax instead of plain require simply would not work and probably the only reason it does it because of the babel transormation? Did I understand your answer correctly?
    – Andy
    Commented Feb 23, 2016 at 18:01
  • 2
    No, it does work because your module loader/bundler (webpack in your case) treats pre-ES6 modules appropriately. Not all loaders/bundlers might support this, it's implementation-dependent. But given how useful it is to import old commonjs modules, this won't break. The problem of your IDE is that it doesn't know about this.
    – Bergi
    Commented Feb 23, 2016 at 18:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.