
Default exports er đ©
React-utvikler Kristofer Giltvedt Selbekk i Bekk mener vi bĂžr slutte med denne kodestilen med en gang.
Jeg vet ikke om du visste det, men default exports er sÄ 2015. Jeg anbefaler at du dropper dem fra kodebasen din til fordel for named exports.
En kjapp recap av exports
FÞr jeg starter full tirade-modus, sÄ er det greit Ä ha med seg flesteparten. SÄ la oss ta en kjapp intro til tematikken jeg skal prate om.
I 2015 kom TC39-komitéen med en haug flotte nyheter til JavaScript. Mens pilfunksjoner og nye mÄter Ä scope variabler pÄ fikk mesteparten av oppmerksomheten, ble folk ogsÄ veldig glad i det nye modulsystemet! Der man fÞr mÄtte skrive JavaScripten sin i én stor fil, eller lage intrikate systemer for emulere at man ikke hadde én stor fil, kunne man nÄ plutselig ha forskjellige filer, med kode i som man eksporterte, og sÄ importerte. Det gjorde ting utrolig mye enklere!
Det ble bestemt at man skulle ha to forskjellige typer Ă„ tilgjengeliggjĂžre kode fra en fil â sĂ„kalte âdefault exportâ-er og ânamed exportsâ. Her er hvordan man gjĂžr det:
// math.js
export default function add(a, b) { return a + b }
export function subtract(a, b) { return a - b }
For Ä bruke denne koden i en annen fil (som i dette eksempelet ligger i samme mappe), sÄ skriver man fÞlgende:
import add from './math'
import { subtract } from './math'
// eventuelt
import add, { subtract } from './math'
Tanken var vel at det man bruker mest, eller det som er âĂ„penbart logiskâ Ă„ bruke fra den filen, burde vĂŠre en default export, mens andre ting burde vĂŠre named exports. Mine antakelser her altsĂ„.
Hvorfor er default exports the worst?
Som du kanskje la merke til i brukseksempelet ovenfor, sĂ„ er det ikke alltid veldig logisk hvorfor noe skal ha Ă©n syntaks, mens noe skal ha en annen. Hvorfor er add hoved-eksporten, mens subtract er ânedgradertâ til navngitt eksport?
Et annet, litt mer realistisk eksempel, kan vĂŠre en React-komponent. Her ser jeg ofte fĂžlgende standard i TypeScript-prosjekter:
export type BoxProps = {
//..
}
export default function Box(props: BoxProps) {
// ..
}
For Ă„ bruke denne koden, ser koden din plutselig slik ut:
import Box, { BoxProps } from './Box'
For det fÞrste synes jeg denne syntaksen er forvirrende, og det synes IDEer ogsÄ. VSCode sliter f.eks. mye mer med Ä importere default exports enn named exports (merk: min erfaring, dette er sikkert lÞsbart pÄ sikt).
For det andre sĂ„ blir det fort enda mer avansert om du skulle vĂŠre sĂ„ uheldig Ă„ lage en fil med flere enn Ă©n komponent i â som er et mĂžnster jeg ofte bruker:
export type BoxProps = {
//..
}
export default function Box(props: BoxProps) {
// ..
}
export type BoxHeadingProps = {
//..
}
export function BoxHeading(props: BoxProps) {
// ..
}
NĂ„ ser plutselig bruken slik ut:
import Box, { BoxProps, BoxHeading, BoxHeadingProps } from './Box'
Man kan selvfĂžlgelig argumentere for at Box -komponenten er âhovedkomponentenâ, og derfor burde ha litt ekstra viktighet i APIet, men den viktigheten kan oppnĂ„s med navngivning istedenfor.
En annen litt klĂžnete ting med default exports er at du ikke kan eksportere konstanter.
export default function yo(name) { console.log(`yo ${name}`) } // ok
export default const yo = name => console.log(`yo ${name}`) // error
Hvorfor de har gjort dette tullete skillet vet fÄglarna, men det er noe jeg til stadighet snubler i.
Bruk named exports
Med named exports, derimot, er alt gull og grÞnne skoger. à auto-importere funksjoner fungerer uten problemer, det er ingen rar syntaks-forskjell mellom én import og en annen, og du kan fint eksportere hva enn du vil som named exports!
Default exports har selvfÞlgelig sine bruksomrÄder de ogsÄ, men de er som regel i eksterne biblioteker med én enkelt funksjon (som f.eks. classnames -biblioteket). Selv her kan man argumentere for at det er vel sÄ greit Ä bruke named exports her ogsÄ, men jeg skal ikke vÊre sÄ sur og gammel.
SĂ„ bruk named exports i kodebasen din. Du og kollegaene dine kommer til Ă„ takke deg i tiden som kommer.