TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Why we have banned default exports in JavaScript

82 点作者 mmmnt超过 7 年前

25 条评论

domenicd超过 7 年前
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 未加载
chrisco255超过 7 年前
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 未加载
alangpierce超过 7 年前
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 未加载
ef4超过 7 年前
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 未加载
frankjr超过 7 年前
<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.
ljharb超过 7 年前
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 未加载
DiThi超过 7 年前
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.
drinchev超过 7 年前
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.
captainmuon超过 7 年前
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 未加载
z3t4超过 7 年前
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 未加载
iamleppert超过 7 年前
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 未加载
krzkaczor超过 7 年前
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 未加载
idontcommentm超过 7 年前
How is this different than just relying on the filename to establish the naming contract for a default export?
seniorsassycat超过 7 年前
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.
hashkb超过 7 年前
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 未加载
jacobr超过 7 年前
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 未加载
dmitriid超过 7 年前
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 未加载
kozak超过 7 年前
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 未加载
coding123超过 7 年前
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.
wmonk超过 7 年前
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_left超过 7 年前
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 未加载
beeskneecaps超过 7 年前
When I shake the tree all the leaves stay on, so default exports are probably fine.
stevebmark超过 7 年前
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.
ape4超过 7 年前
They could have a `private` keyword like Java.
hungerstrike超过 7 年前
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>