[ Web Proxy ]
URL:
Viewing: https://es.javascript.info/import-export [Back]  [Original]

Export e Import
ES

Queremos que este proyecto de cdigo abierto est disponible para personas de todo el mundo.

Ayuda a traducir el contenido de este tutorial a tu idioma!

    Buscar en Javascript.info:
    Buscar en el tutorial:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Export e Import

    Las directivas export e import tienen varias formas de sintaxis.

    En el artculo anterior vimos un uso simple, ahora exploremos ms ejemplos.

    Export antes de las sentencias

    Podemos exportar cualquier declaracin colocando antes export, ya sea a una variable, funcin o clase.

    Por ejemplo, aqu todas las exportaciones son vlidas:

    // exportar un array
    export let months = ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    
    // exportar una constante
    export const MODULES_BECAME_STANDARD_YEAR = 2015;
    
    // exportar una clase
    export class User {
      constructor(name) {
        this.name = name;
      }
    }
    Sin punto y coma despus de export clase/funcin

    Tenga en cuenta que export antes de una clase o una funcin no la hace una expresin de funcin. Sigue siendo una declaracin de funcin, aunque exportada.

    La mayora de las guas de estilos JavaScript no recomiendan punto y coma despus de declarar funciones y clases.

    Es por esto que no hay necesidad de un punto y coma al final de export class y export function:

    export function sayHi(user) {
      alert(`Hello, ${user}!`);
    }  // sin ; al final

    Export separado de la declaracin

    Tambin podemos colocar export por separado.

    Aqu primero declaramos y luego exportamos:

    //  say.js
    function sayHi(user) {
      alert(`Hello, ${user}!`);
    }
    
    function sayBye(user) {
      alert(`Bye, ${user}!`);
    }
    
    export {sayHi, sayBye}; // una lista de variables exportadas

    O, tcnicamente podemos colocar export arriba de las funciones tambin.

    Import *

    Generalmente, colocamos una lista de lo que queremos importar en llaves import {...}, de esta manera:

    //  main.js
    import {sayHi, sayBye} from './say.js';
    
    sayHi('John'); // Hello, John!
    sayBye('John'); // Bye, John!

    Pero si hay mucho para importar, podemos importar todo como un objeto utilizando import * as <obj>, por ejemplo:

    //  main.js
    import * as say from './say.js';
    
    say.sayHi('John');
    say.sayBye('John');

    A primera vista, importar todo parece algo tan genial, corto de escribir, por qu deberamos listar explcitamente lo que necesitamos importar?

    Pues hay algunas razones.

    1. Listar explcitamente qu importar da nombres ms cortos: sayHi() en lugar de say.sayHi().
    2. La lista explcita de importaciones ofrece una mejor visin general de la estructura del cdigo: qu se usa y dnde. Facilita el soporte de cdigo y la refactorizacin.
    No temas hacer demasiados import

    Las herramientas de empaquetado modernas, como webpack y otras, unen los mdulos, optimizan la velocidad de carga, y eliminan las importaciones no usadas.

    Por ejemplo, si importas import * as library desde una librera de cdigo enorme, y usas solo unos pocos mtodos, los que no se usen no sern incluidos en el paquete optimizado.

    Importar as

    Tambin podemos utilizar as para importar bajo nombres diferentes.

    Por ejemplo, importemos sayHi en la variable local hi para brevedad, e importar sayBye como bye:

    //  main.js
    import {sayHi as hi, sayBye as bye} from './say.js';
    
    hi('John'); // Hello, John!
    bye('John'); // Bye, John!

    Exportar as

    Existe un sintaxis similar para export.

    Exportemos funciones como hi y bye:

    //  say.js
    ...
    export {sayHi as hi, sayBye as bye};

    Ahora hi y bye son los nombres oficiales exportados, los que usarn otros mdulos al hacer sus importaciones.

    //  main.js
    import * as say from './say.js';
    
    say.hi('John'); // Hello, John!
    say.bye('John'); // Bye, John!

    Export default

    En la prctica, existen principalmente dos tipos de mdulos.

    1. Mdulos que contienen una librera, un paquete de funciones como say.js de arriba.
    2. Mdulos que declaran una entidad simple, por ejemplo un mdulo user.js que exporta nicamente class User.

    Principalmente, se prefiere el segundo enfoque, de modo que cada cosa reside en su propio mdulo.

    Naturalmente, eso requiere muchos archivos, ya que todo quiere su propio mdulo, pero eso no es un problema en absoluto. En realidad, la navegacin de cdigo se vuelve ms fcil si los archivos estn bien nombrados y estructurados en carpetas.

    Los mdulos proporcionan una sintaxis especial export default (la exportacin predeterminada) para que la forma de una cosa por mdulo se vea mejor.

    Poner export default antes de la entidad a exportar:

    //  user.js
    export default class User { // slo agregar "default"
      constructor(name) {
        this.name = name;
      }
    }

    Slo puede existir un slo export default por archivo.

    Y luego importarlo sin llaves:

    //  main.js
    import User from './user.js'; // no {User}, slo User
    
    new User('John');

    Las importaciones sin llaves se ven mejor. Un error comn al comenzar a usar mdulos es olvidarse de las llaves. Entonces, recuerde, import necesita llaves para las exportaciones con nombre y no las necesita para la predeterminada.

    Export con nombre Export predeterminada
    export class User {...} export default class User {...}
    import {User} from ... import User from ...

    Tcnicamente, podemos tener exportaciones predeterminadas y con nombre en un solo mdulo, pero en la prctica la gente generalmente no las mezcla. Un mdulo tiene exportaciones con nombre o la predeterminada.

    Como puede haber como mximo una exportacin predeterminada por archivo, la entidad exportada puede no tener nombre.

    Por ejemplo, todas estas son exportaciones predeterminadas perfectamente vlidas:

    export default class { // sin nombre de clase
      constructor() { ... }
    }
    export default function(user) { // sin nombre de funcin
      alert(`Hello, ${user}!`);
    }
    // exportar un nico valor, sin crear una variable
    export default ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

    No dar un nombre est bien, porque solo hay un export default por archivo, por lo que import sin llaves sabe qu importar.

    Sin default, dicha exportacin dara un error:

    export class { // Error! (exportacin no predeterminada necesita un nombre)
      constructor() {}
    }

    El nombre default

    En algunas situaciones, la palabra clave default se usa para hacer referencia a la exportacin predeterminada.

    Por ejemplo, para exportar una funcin por separado de su definicin:

    function sayHi(user) {
      alert(`Hello, ${user}!`);
    }
    
    // lo mismo que si agregamos "export default" antes de la funcin
    export {sayHi as default};

    Otra situacin, supongamos un mdulo user.js exporta una cosa principal default, y algunas cosas con nombre (raro el caso, pero sucede):

    //  user.js
    export default class User {
      constructor(name) {
        this.name = name;
      }
    }
    
    export function sayHi(user) {
      alert(`Hello, ${user}!`);
    }

    Aqu la manera de importar la exportacin predeterminada junto con la exportacin con nombre:

    //  main.js
    import {default as User, sayHi} from './user.js';
    
    new User('John');

    Y por ltimo, si importamos todo * como un objeto, entonce la propiedad default es exactamente la exportacin predeterminada:

    //  main.js
    import * as user from './user.js';
    
    let User = user.default; // la exportacin predeterminada
    new User('John');

    Unas palabras contra exportaciones predeterminadas

    Las exportaciones con nombre son explcitas. Nombran exactamente lo que importan, as que tenemos esa informacin de ellos; Eso es bueno.

    Las exportaciones con nombre nos obligan a usar exactamente el nombre correcto para importar:

    import {User} from './user.js';
    // import {MyUser} no funcionar, el nombre debe ser {User}

    Mientras que para una exportacin predeterminada siempre elegimos el nombre al importar:

    import User from './user.js'; // funciona
    import MyUser from './user.js'; // tambin funciona
    // puede ser import Cualquiera... y aun funcionara

    Por lo tanto, los miembros del equipo pueden usar diferentes nombres para importar lo mismo, y eso no es bueno.

    Por lo general, para evitar eso y mantener el cdigo consistente, existe una regla que establece que las variables importadas deben corresponder a los nombres de los archivos, por ejemplo:

    import User from './user.js';
    import LoginForm from './loginForm.js';
    import func from '/path/to/func.js';
    ...

    An as, algunos equipos lo consideran un serio inconveniente de las exportaciones predeterminadas. Por lo tanto, prefieren usar siempre exportaciones con nombre. Incluso si solo se exporta una sola cosa, todava se exporta con un nombre, sin default.

    Eso tambin hace que la reexportacin (ver ms abajo) sea un poco ms fcil.

    Reexportacin

    La sintaxis Reexportar export ... from ... permite importar cosas e inmediatamente exportarlas (posiblemente bajo otro nombre), de esta manera:

    export {sayHi} from './say.js'; // reexportar sayHi
    
    export {default as User} from './user.js'; // reexportar default

    Por qu se necesitara eso? Veamos un caso de uso prctico.

    Imagine que estamos escribiendo un paquete: una carpeta con muchos mdulos, con algunas de las funciones exportadas al exterior (herramientas como NPM nos permiten publicar y distribuir dichos paquetes pero no estamos obligados a usarlas), y muchos mdulos son solo ayudantes, para uso interno en otros mdulos de paquete.

    La estructura de archivos podra ser algo as:

    auth/
        index.js
        user.js
        helpers.js
        tests/
            login.js
        providers/
            github.js
            facebook.js
            ...

    Nos gustara exponer la funcionalidad del paquete a travs de un nico punto de entrada.

    En otras palabras, una persona que quiera usar nuestro paquete, debera importar solamente el archivo principal auth/index.js.

    Como esto:

    import {login, logout} from 'auth/index.js'

    El archivo principal, auth/index.js, exporta toda la funcionalidad que queremos brindar en nuestro paquete.

    La idea es que los desarrolladores que usen nuestro paquete no deban lidiar con su estructura interna, buscar archivos dentro de nuestra carpeta de paquetes. Exportamos solo lo que es necesario en auth/index.js y mantenemos el resto oculto a miradas indiscretas.

    Como la funcionalidad real exportada se encuentra dispersa entre el paquete, podemos importarla en auth/index.js y exportar desde ella:

    //  auth/index.js
    
    // importar login/logout e inmediatamente exportarlas
    import {login, logout} from './helpers.js';
    export {login, logout};
    
    // importar default como User y exportarlo
    import User from './user.js';
    export {User};
    ...

    Ahora los usuarios de nuestro paquete pueden hacer esto import {login} from "auth/index.js".

    La sintaxis export ... from ... es solo una notacin ms corta para tal importacin-exportacin:

    //  auth/index.js
    // re-exportar login/logout
    export {login, logout} from './helpers.js';
    
    // re-exportar export default como User
    export {default as User} from './user.js';
    ...

    La diferencia notable de export ... from comparado a import/export es que los mdulos re-exportados no estn disponibles en el archivo actual. Entonces en el ejemplo anterior de auth/index.js no podemos usar las funciones re-exportadas login/logout.

    Reexportando la exportacin predeterminada

    La exportacin predeterminada necesita un manejo separado cuando se reexporta.

    Digamos que tenemos user.js con export default class User, y nos gustara volver a exportar la clase User de l:

    //  user.js
    export default class User {
      // ...
    }

    Podemos tener dos problemas:

    1. export User from './user.js' no funcionar. Nos dar un error de sintaxis.

      Para reexportar la exportacin predeterminada, tenemos que escribir export {default as User}, tal como en el ejemplo de arriba.

    2. export * from './user.js' reexporta nicamente las exportaciones con nombre, pero ignora la exportacin predeterminada.

      Si queremos reexportar tanto la exportacin con nombre como la predeterminada, se necesitan dos declaraciones:

      export * from './user.js'; // para reexportar exportaciones con nombre
      export {default} from './user.js'; // para reexportar la exportacin predeterminada

    Tales rarezas de reexportar la exportacin predeterminada son una de las razones por las que a algunos desarrolladores no les gustan las exportaciones predeterminadas y prefieren exportaciones con nombre.

    Resumen

    Aqu estn todos los tipos de exportacin que cubrimos en este y en artculos anteriores.

    Puede comprobarlo al leerlos y recordar lo que significan:

    • Antes de la declaracin de clase/funcin/:
      • export [default] clase/funcin/variable ...
    • Export independiente:
      • export {x [as y], ...}.
    • Reexportar:
      • export {x [as y], ...} from "module"
      • export * from "module" (no reexporta la predeterminada).
      • export {default [as y]} from "module" (reexporta la predeterminada).

    Importacin:

    • Importa las exportaciones con nombre:
      • import {x [as y], ...} from "module"
    • Importa la exportacin predeterminada:
      • import x from "module"
      • import {default as x} from "module"
    • Importa todo:
      • import * as obj from "module"
    • Importa el mdulo (su cdigo se ejecuta), pero no asigna ninguna de las exportaciones a variables:
      • import "module"

    Podemos poner las declaraciones import/export en la parte superior o inferior de un script, eso no importa.

    Entonces, tcnicamente este cdigo est bien:

    sayHi();
    
    // ...
    
    import {sayHi} from './say.js'; // import al final del archivo

    En la prctica, las importaciones generalmente se encuentran al comienzo del archivo, pero eso es solo para mayor comodidad.

    Tenga en cuenta que import y export solo funcionan en el nivel superior del mdulo, no dentro de ningn bloque {...}.

    Una importacin condicional como esta no funcionar:

    if (something) {
      import {sayHi} from "./say.js"; // Error: import debe estar en nivel superior
    }

    Pero qu pasa si realmente necesitamos importar algo condicionalmente? O en el momento adecuado? Por ejemplo, cargar un mdulo a pedido, cuando realmente se necesita.

    Veremos importaciones dinmicas en el prximo artculo.

    Mapa del Tutorial

    Comentarios

    lea esto antes de comentar
    • Si tiene sugerencias sobre qu mejorar, por favor enviar una propuesta de GitHub o una solicitud de extraccin en lugar de comentar.
    • Si no puede entender algo en el artculo, por favor explique.
    • Para insertar algunas palabras de cdigo, use la etiqueta <code>, para varias lneas envolverlas en la etiqueta <pre>, para ms de 10 lneas utilice una entorno controlado (sandbox) (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page