Why default exports are bad

Import statements come in a lot of different flavors in JavaScript and where there is variation some of the options are often better than others. For import statements we want to easily understand which parts of a module we are going to use and also easily get an overview of where those parts are being used throughout our projects.

Here is a list borrowed from the MDN documentation:

import defaultExport from "module-name";
import * as name from "module-name";
import { export1 } from "module-name";
import { export1 as alias1 } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export1 [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";
var promise = import("module-name");

When using default exports you can name the variable in any way you want. This might lead to varying naming each time a module is imported. Consistent naming is especially important in JavaScript you will likely need to search through your project files each time you refactor a modules API to see where that API is used. If your naming is not consistent it makes finding all uses really hard.

In more strongly typed languages the IDEs will generally assist you much more to find uses of specific functions and classes, but due to JavaScript's dynamically typed nature it will often prove harder without consistent naming.

If you however always use destructuring assignments like import { export1 } from "module-name"; when importing you can ensure that any imported variables will always be consistently named. If you by accident misspell a variable when deconstructing the code will also crash once it reaches that import statement.

Bye for now!