TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Why we have banned default exports in JavaScript

82 pointsby mmmntover 7 years ago

25 comments

domenicdover 7 years ago
The historical claim, that default exports we&#x27;re introduced for compatibility with CommonJS&#x2F;Node, is not accurate.<p>Default exports were introduced because often a module wants to export a single value or piece of functionality. In such cases, in module systems where all exports are named, the author of the module and its consumer have to coordinate on some convention to indicate &quot;this is the thing&quot;. For example, some languages choose the same as the file name (with fun casing consequences or conversions). Some choose a particular name like &quot;t&quot; (I&#x27;ve heard one of the MLs does this). Some don&#x27;t have a convention at all and you have to consult the documentation for each import.<p>When designing JS modules, we decided to bake in a single somewhat-privileged export name for these cases, &quot;default&quot;, which gets nice syntax on both the export and import sides to help encourage ecosystem standardization and coordination.<p>You can choose to deviate from it, in favor of your own convention. (It seems like the author prefers some kind of filename-converted-to-camelCase for their projects.) But do so being aware you&#x27;re walking away from the ecosystem affordances and it will be unexpected for your consumers.
评论 #15769523 未加载
chrisco255over 7 years ago
Two of the three reasons listed involve refactoring and autocomplete quirks of Visual Studio Code, specifically. For instance, Webstorm has no such issues with default exports. It is smart enough to find all uses of a module and to track them down. The third reason is not all that common in my experience. Tree shaking is an optimization and often a premature one. It&#x27;s also a technique primarily used for third party libraries.<p>My problem with this article is the advice is far too broad &quot;ban all default exports&quot; without being considerate of how others code.<p>For example, I prefer to keep my modules small, with only one export. I may export helper or unwrapped versions of higher order components for easier testing, but generally I want my modules small and single purpose.<p>Default exports are helpful constructs. Disagree with this article overall.
评论 #15766754 未加载
评论 #15766240 未加载
alangpierceover 7 years ago
Default exports also have some oddities involving live bindings, since the typical syntax is to export an expression, not a binding, but there are workarounds to make it a real live binding. Here&#x27;s a GitHub discussion where some people who are pretty good with JavaScript are trying to figure out how to properly implement default exports: <a href="https:&#x2F;&#x2F;github.com&#x2F;rollup&#x2F;rollup&#x2F;issues&#x2F;1078" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;rollup&#x2F;rollup&#x2F;issues&#x2F;1078</a><p>Particularly this comment, which agrees that default exports were a mistake: <a href="https:&#x2F;&#x2F;github.com&#x2F;rollup&#x2F;rollup&#x2F;issues&#x2F;1078#issuecomment-268286496" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;rollup&#x2F;rollup&#x2F;issues&#x2F;1078#issuecomment-26...</a>
评论 #15767355 未加载
ef4over 7 years ago
I keep seeing this misconception repeated.<p>Both default and named exports can be rebound to new symbols locally. But that has no effect on how statically analyzable the code is.<p>“It can’t be auto refactored” just isn’t true. If it’s true for your particular tool, file a bug.<p>People are using a cargo cult understanding of how code analysis works. It’s not just grepping for a string.
评论 #15766794 未加载
frankjrover 7 years ago
<i>Default exports don’t export any name ie. symbol that can be easily associated with a exported value. Named exports, on the other hand, are all about having a name (pretty obvious right ) . This makes possible for IDEs to find and import dependencies for you automatically, which is a huge productivity boost.</i><p>There&#x27;s no reason a default export cannot have a name.<p><pre><code> export default function foo() {...} </code></pre> With this in place VS Code is able to auto-import the dependency and refactor its name if necessary.
ljharbover 7 years ago
A default export is what a module <i>is</i>; a named export is what a module <i>has</i>.<p>Both tools are useful; both are necessary; most modules should have a single default export.
评论 #15766594 未加载
评论 #15766300 未加载
DiThiover 7 years ago
I agree for different reasons. In our code we never export a single value without name because it&#x27;s not consistent. Many of our modules export a single class with the same name as the module. One less thing to remember.<p>I dislike when I use some external module and I have to look up whether the module is the value or not...<p>Edit: as an additional annoyance, when mixing CommonJS and ES6, the value may be in an element called &quot;default&quot;. In some cases. I&#x27;m still unsure when.
drinchevover 7 years ago
What I feel strange about default export is that you can actually mix it with named exports.<p><pre><code> export default class Foo { } export const Bar = &quot;&quot;; </code></pre> and then<p><pre><code> import Foo, { Bar } from &quot;.&#x2F;module&quot; </code></pre> I would expect if a module has a default export, then it should not have named ones. Why? At least it puts more structure in your code architecture.
captainmuonover 7 years ago
As someone who only occasionally uses JavaScript, module imports are really confusing. Often, I want to do<p><pre><code> import * as mymodule from &#x27;.&#x2F;mymodule&#x27; </code></pre> Namely, treat the whole module as one thing, and give it a name. It would be great if you could do that without specifying the name manually, e.g. like &quot;import mymodule&quot; in Python.<p>The other times, I do:<p><pre><code> import SingleClass from &#x27;.&#x2F;singleclass&#x27; # or import {SingleClass} from &#x27;.&#x2F;singleclass&#x27; </code></pre> Its rather rare that I want a handfull of single things from a module - either one or all (all can mean &quot;one object that has everything&quot; or &quot;all functions and constants in one wrapper&quot;, depending on how stuff is exported). The only time I need the `import {a,b,c} from &#x27;.&#x2F;utils&#x27;` syntax is usually with a grab-bag util function module.<p>You get used to it, but I sometimes wish things were more like Python.
评论 #15768056 未加载
评论 #15767489 未加载
z3t4over 7 years ago
I can for my life not understand why the standards committee did not make the NodeJS module system the standard, what where they thinking !?
评论 #15766061 未加载
评论 #15766020 未加载
评论 #15766909 未加载
评论 #15766068 未加载
iamleppertover 7 years ago
I&#x27;ll preface this by saying I&#x27;m not a huge fan of ES2015 modules. Everything ES2015 provides (syntactical sugar) could be achieved with CommonJS exports. If you don&#x27;t want to export an object and only a single thing, you can enforce those restrictions via code reviews, linting tools, etc. rather than bloating the language spec. And the backwards compatibility is very poor with older CommonJS (the weird __default stuff). This is what happens when you try to bolt on features from other languages that make no sense with javascript.<p>The next point is regarding IDE&#x27;s. Honestly, I don&#x27;t understand the obsession with designing a language around tooltips in an IDE. I personally use vim and once I know a code base I rarely need to look stuff up. If your code and internal APIs are that complicated where you can&#x27;t remember basic function signatures, its time to refactor and simplify so you can fit all that stuff in your memory without the need for hints.<p>To the point about refactoring: I really doubt named imports are going to save you much time here at all. How much time do you spend figuring out the import&#x2F;exports from a file vs. refactoring what the actual code is doing? Unless you&#x27;re talking about some kind of formal AST automation (which could benefit from being more explicit)?<p>The next comment is about tree shaking. Better known as &quot;dead code elimination&quot; and its been in uglifiyjs and closure compiler for 10 years but somehow the webpack folks thought tree shaking sounded cooler, even though they don&#x27;t even implement it and just shell out to uglifer. My argument here is that if your code is so messy and is in need of good shake (no pun intended, well...err), you have big problems. I cringe when I see people trying to layer on tools to paper over technical debt. You should actually go through the source and remove what isn&#x27;t needed or used anymore.
评论 #15766124 未加载
评论 #15766278 未加载
评论 #15766035 未加载
评论 #15766032 未加载
评论 #15765992 未加载
krzkaczorover 7 years ago
The author here, it&#x27;s great to finally make it to the front page, thanks! :D Initial inspiration for writing this post was twitter discussion: <a href="https:&#x2F;&#x2F;twitter.com&#x2F;krzKaczor&#x2F;status&#x2F;933705625883889664" rel="nofollow">https:&#x2F;&#x2F;twitter.com&#x2F;krzKaczor&#x2F;status&#x2F;933705625883889664</a>
评论 #15765916 未加载
idontcommentmover 7 years ago
How is this different than just relying on the filename to establish the naming contract for a default export?
seniorsassycatover 7 years ago
I might take the opposite stance and ban destructed named imports, preferring default and wildcard imports.<p><pre><code> import function from &#x27;function&#x27;; import * as module from &#x27;module&#x27;; </code></pre> Why wildcard imports over named imports?<p>Wildcards preserve context. `ReactDOM.render` means more than `render`. Using wildcards avoids collisions - lodash, http, https each have a named export `get` [0]. Wildcards still supports tree shaking! Try it in webpack or rollup - only the named exports that you access will be included in the shooken bundle [1].<p>[0]: Yeah, I know you can import { get as httpsGet }, but why would I want to?<p>[1]: Unless you treat the binding as an object. `Object.keys(module)` will break tree-shaking.
hashkbover 7 years ago
Sometimes you don&#x27;t care what the importing module names your thing, and it&#x27;s the only thing your module does. Think of a super simple React component... I&#x27;m `export default function(props) { ... }`ing that every time. Is that bad?
评论 #15765941 未加载
评论 #15769145 未加载
jacobrover 7 years ago
I use TypeScript and VSCode and recognise the easier refactoring, but almost all external dependencies will use default exports, so you just end up with an inconsistent code base.
评论 #15766108 未加载
dmitriidover 7 years ago
I&#x27;d ban default exports if and only if JS had a Java-like import syntax declaration.<p><pre><code> import {x,y,z} from &#x27;module&#x27; </code></pre> ^ this is an abomination
评论 #15766093 未加载
kozakover 7 years ago
Semantic difference between default and named exports is that as a user of the module you are forced to choose a name for the default export, and these names will likely be different across different usages of the module. For linking units within one project, this is a bad thing, because you should be consistent in naming your things. But for modules that are published to the global NPM, maybe why not.
评论 #15766168 未加载
评论 #15766082 未加载
coding123over 7 years ago
Thanks for writing this up, I had similar feelings about default exports and there are very few articles that discuss this. Many examples out there use default exports and it&#x27;s just bad form to export in that form when there are classes functions and variables that might be referenced directly.
wmonkover 7 years ago
Surely there are drawbacks in refactoring, as unless your editor supports bulk renaming references you will have to rename every single import and usage. Whereas with a default export you have no such issue.
fold_leftover 7 years ago
While reading this thread away from my machine, I&#x27;m curious now what happens when<p>export default { foo: 2 };<p>export const foo = 3;<p>&#x2F;&#x2F; other file<p>import { foo } from &#x27;.&#x2F;file&#x27;<p>console.log(foo);<p>Presumably last one wins or, if the other way around, a reassignment of const error?
评论 #15831386 未加载
评论 #15770392 未加载
beeskneecapsover 7 years ago
When I shake the tree all the leaves stay on, so default exports are probably fine.
stevebmarkover 7 years ago
If you use an IDE like Visual Studio Code or Webstorm, and not a text editor like Sublime, then it autocompletes default exports perfectly fine. Just stop writing code in a text editor like Sublime&#x2F;Vim&#x2F;Emacs&#x2F;Atom&#x2F;etc.
ape4over 7 years ago
They could have a `private` keyword like Java.
hungerstrikeover 7 years ago
Well, the most widely used style guide [0] and Facebook and many others including myself disagree. I&#x27;d rather see default exports everywhere so I only ever have to import one thing from your file.<p>None of the points made in the article are even valid.<p>1) You don&#x27;t get better DX because you simply cannot use the same symbol name everywhere all the time anyway because names clash.<p>2) With point 1 gone, point 2 is wiped out as well.<p>3) This is patently false.<p>[0] <a href="https:&#x2F;&#x2F;github.com&#x2F;airbnb&#x2F;javascript#modules--prefer-default-export" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;airbnb&#x2F;javascript#modules--prefer-default...</a>