Break stuff. Now.

Avoid Default Exports

One does not simply export one thing from a module

February 1, 2018

It's the start of a new sprint. Another opportunity to refactor a huge swathe of undesirable code, update dependencies, break and unbreak builds, that sort of thing. The idea of refactoring incorporated into the daily run is a good thing to do, keeps technical debt at bay. This time around, I had to remove default exports from ALL of my modules.

ES paved the way for modules. TS paved the way to typed JS. Angular made client-side code pretend like it was Spring. All this would lead you to believe that you can write client-side code ala Java, where you had a class per file...

// OMG, this looks so Java-ish.
import {Injectable} from '@angular/core'
import {MyOtherService} from './path/to/my-other.service'

export default class MyServiceClass {

    private myOtherService: MyOtherService


...until you start seeing smoke coming from your IDE.

// OMG! The inconsistency! My eyes!
import MyDefaultExport, {MyOtherExport} from 'path/to/MyService'
import {MyOtherExport, default as MyDefaultExport} from 'path/to/MyService'

The above was a result of me thinking that I can write client-side service classes ala Java. But what happened, due to JavaScript's (and to some extent, TypeScript's) terseness and the class not growing as fat as I thought it would, related things like interfaces, enums and support classes all went into the same file. This resulted in a mixed-style import-export experience. What drew the final straw was when a collegue asked what's the difference between the stuff in {} and the stuff outside. I just blew away all default exports after that.


// Much more consistent.
import {MyExport, MyOtherExport, YetAnotherExport} from 'path/to/MyService'

Default exports have their purpose, and I like the idea of being given a lot of options to work with (as long as they don't impact anything when not used). However, I suggest you avoid writing your modules with the initial thought that there will only ever be one export. Just use named exports, even if you're exporting one thing. It's safer that way.