Exportaciones ESM: ¿nombradas o por defecto?
¿Nombrar o no nombrar?
¿Deberías usar exportaciones named o default en JavaScript?
No faltan artículos con opiniones tajantes sobre este tema.
La mayoría juzga default export como “terrible”. Otros sostienen que default debería ganar (por ejemplo, la guía de estilo de AirBnb).
A menudo culpan a cosas enteramente temporales: errores de auto-importación del IDE, capacidades de tree-shaking de un bundler en particular, o la mera posibilidad de errores tipográficos al nombrar una importación.
¿Acaso hemos perdido el punto de exportar en primer lugar?
El código es comunicación. ✨
Le estamos enviando una señal a los
importers sobre cómo usar algo.
Entonces, ¿qué estamos diciendo?
En términos generales, hay 2 formas de exportar cosas en JavaScript moderno:
- Un
export defaultdeclara audazmente “Esta es LA COSA MÁS IMPORTANTE.” Además, “cualquier exportación nombrada solo juega un rol secundario.” - Una
exportación nombradadice que es “definitivamente UNA COSA.” También plantea algunas preguntas, “¿tienes otros compañeros por ahí?” Seguimiento: “¿Están invitados o son obligatorios?”
Por supuesto, puedes combinar ambos o usar diferentes enfoques para distintas partes de tu base de código. Ver más ejemplos al final del artículo.
Argumentos débiles, amigo
Abordemos algunos de los “problemas temporales” comunes con los que la gente se encuentra.
- Argumento #1: Las exportaciones nombradas aseguran consistencia en los nombres. fuente
- No, no lo hacen. ¿Quizás estás buscando una regla de lint?
- (Odio ser quien te lo diga, ¡pero espera a ver lo que pueden hacer las variables!)
// ¡Puedes usar alias con ambas!import { Knife as Handle } from "./knife.js"; // 🔪import { default as Handle } from "./knife.js"; // 🔪import Handle from "./knife.js"; // 🔪-
Argumento #2: Usa
import * as soManyKnives from './kinves.js'para combinar exportaciones nombradas. (Sin enlace, el autor se retractó.)- Función interesante. No es el punto.
- Ahora dime, ¿cómo sostengo tu invento otra vez? Sin intención del autor.
-
Argumento #3: Las exportaciones nombradas tienen mejor soporte de importación o renombrado en el IDE. fuente
-
Incorrecto (ya no más). Configura/actualiza tus herramientas.
-
El soporte existe desde hace más de 3 años en VS Code, IntelliJ, etc.
-
Aun así, hay algunas “buenas prácticas” para usar con
default exportsy obtener la mejor experiencia de IDE y refactorización. -
✅
export default function UserService() {}- siempre prefiere funciones nombradas. -
❌
export default function() { }- las funciones anónimas no están implícitamente ligadas a su nombre de archivo. Si no nombras la cosa, es difícil pedirle a la computadora que la cambie. -
Nota: Por razones históricas, no puedes combinar
export defaultcon una expresiónconst.export default const Knife = () => {...blade, ...handle}// ^ ❌ No soportado ❌ ^// No se puede exportar default const ....// ==========================// Sin embargo, una vez declarada, puedes exportar una variable const como default.const Knife = () => {...blade, ...handle}export default Knife;// ^ ✅ Válido// Para completar:export default class anyoneStillUseThese {}// ^ ✅ También es válido exportar una clase como default
-
Resumen
En realidad hay muchas combinaciones de formas en que podríamos exportar cosas, cada una cuenta una historia diferente:
| Default (Exports) | Named (Exports) | Private Fns | Patrón | Significado |
|---|---|---|---|---|
| ✅ | ❌ | ❌ | Una exportación por defecto. | ”¡Presentando UNA función con un solo propósito!” |
| ❌ | ✅ | ❌ | Una exportación nombrada. | ”Por favor, no me renombres.” |
| ✅ | ✅ | ✅ | Exportación por defecto + múltiples funciones ‘privadas’ no exportadas | ”Aquí hay algo de lógica relacionada. Además, espera comportamiento tipo clase.” |
| ❌ | ❌ | ✅ | Múltiples exportaciones nombradas, nombre de archivo genérico. | ”Un conjunto de cosas vagamente relacionadas, sin jerarquía implícita.” |
| ✅ | ✅ | ❌ | Una única exportación nombrada TAMBIÉN exportada como default. | ”No puedes equivocarte al importarme.” |
Algo en lo que pensar: ¿Qué estamos diciendo cuando el nombre del archivo coincide o no con una de sus exportaciones? (Por ejemplo, un utils.js con muchas funciones.)
Conclusión
Si el código es comunicación, por favor exporta como si en verdad te importara. 💞