diff --git a/1-js/13-modules/02-import-export/article.md b/1-js/13-modules/02-import-export/article.md index 4bd41a168..ea864d19e 100644 --- a/1-js/13-modules/02-import-export/article.md +++ b/1-js/13-modules/02-import-export/article.md @@ -1,50 +1,50 @@ -# Export and Import -Export and import directives have several syntax variants. +# Export e Import -In the previous article we saw a simple use, now let's explore more examples. +Las directivas export e import tienen varias variantes de sintáxis. -## Export before declarations +En el artículo anterior vimos un uso simple, ahora exploremos más ejemplos. -We can label any declaration as exported by placing `export` before it, be it a variable, function or a class. +## Export antes de las sentencias -For instance, here all exports are valid: +Podemos etiquetar cualquier sentencia como exportada colocando 'export' antes, ya sea una variable, función o clase. + +Por ejemplo, aquí todas las exportaciones son válidas: ```js -// export an array +// exportar un array *!*export*/!* let months = ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; -// export a constant +// exportar una constante *!*export*/!* const MODULES_BECAME_STANDARD_YEAR = 2015; -// export a class -*!*export*/!* class User { +// exportar una clase +*!*export*/!* clase User { constructor(name) { this.name = name; } } ``` -````smart header="No semicolons after export class/function" -Please note that `export` before a class or a function does not make it a [function expression](info:function-expressions). It's still a function declaration, albeit exported. +````smart header="Sin punto y coma después de export clase/función" +Tenga en cuenta que `export` antes de una clase o una función no la hace una [expresión de función](info:function-expressions). Sigue siendo una declaración de función, aunque exportada. -Most JavaScript style guides don't recommend semicolons after function and class declarations. +La mayoría de las guías de estilos JavaScript no recomiendan los punto y comas después de declarar funciones y clases. -That's why there's no need for a semicolon at the end of `export class` and `export function`: +Es por esto que no hay necesidad de un punto y coma al final de `export class` y `export function`: ```js export function sayHi(user) { alert(`Hello, ${user}!`); } *!* // no ; at the end */!* ``` - ```` -## Export apart from declarations +## Export separado de la declaración -Also, we can put `export` separately. +También podemos colocar `export` por separado. -Here we first declare, and then export: +Aquí primero declaramos y luego exportamos: ```js // 📁 say.js @@ -57,15 +57,15 @@ function sayBye(user) { } *!* -export {sayHi, sayBye}; // a list of exported variables +export {sayHi, sayBye}; // una lista de variables exportadas */!* ``` -...Or, technically we could put `export` above functions as well. +...O, técnicamente podemos colocar `export` arriba de las funciones también. ## Import * -Usually, we put a list of what to import in curly braces `import {...}`, like this: +Generalmente, colocamos una lista de lo que queremos importar en llaves `import {...}`, de esta manera: ```js // 📁 main.js @@ -77,7 +77,7 @@ sayHi('John'); // Hello, John! sayBye('John'); // Bye, John! ``` -But if there's a lot to import, we can import everything as an object using `import * as `, for instance: +Pero si hay mucho para importar, podemos importar todo como un objeto utilizando `import * as `, por ejemplo: ```js // 📁 main.js @@ -89,13 +89,14 @@ say.sayHi('John'); say.sayBye('John'); ``` -At first sight, "import everything" seems such a cool thing, short to write, why should we ever explicitly list what we need to import? +A primera vista, "importar todo" parece algo tan genial, corto de escribir, por qué deberíamos listar explícitamente lo que necesitamos importar? -Well, there are few reasons. +Pues hay algunas razones. -1. Modern build tools ([webpack](http://webpack.github.io) and others) bundle modules together and optimize them to speedup loading and remove unused stuff. +1. Las herramientas de ensamblaje modernas ([webpack](http://webpack.github.io) y otras) empaquetan los módulos juntos y los optimiza para acelerar la carga y quitan las cosas sin usar. + +Digamos que agregamos una librería externa `say.js` a nuestro proyecto con varias funciones: - Let's say, we added a 3rd-party library `say.js` to our project with many functions: ```js // 📁 say.js export function sayHi() { ... } @@ -103,21 +104,23 @@ Well, there are few reasons. export function becomeSilent() { ... } ``` - Now if we only use one of `say.js` functions in our project: + Ahora si solamnente utilizamos una de las funciones de `say.js` en nuestro proyecto: + ```js // 📁 main.js import {sayHi} from './say.js'; ``` - ...Then the optimizer will see that and remove the other functions from the bundled code, thus making the build smaller. That is called "tree-shaking". + +...Entonces el optimizador lo verá y eliminará las otras funciones del código empaquetado, por lo tanto la compilación es más pequeña. Esto se llama "tree-shaking". -2. Explicitly listing what to import gives shorter names: `sayHi()` instead of `say.sayHi()`. -3. Explicit list of imports gives better overview of the code structure: what is used and where. It makes code support and refactoring easier. +2. Listar explícitamente qué importar da nombres más cortos: `sayHi()` en lugar de `say.sayHi()`. +3. La lista explícita de importaciones ofrece una mejor visión general de la estructura del código: qué se usa y dónde. Facilita el soporte de código y la refactorización. -## Import "as" +## Importar "as" -We can also use `as` to import under different names. +También podemos utilizar `as` para importar bajo nombres diferentes. -For instance, let's import `sayHi` into the local variable `hi` for brevity, and import `sayBye` as `bye`: +Por ejemplo, importemos `sayHi` en la variable local `hi` para brevedad, e importar `sayBye` como `bye`: ```js // 📁 main.js @@ -129,11 +132,11 @@ hi('John'); // Hello, John! bye('John'); // Bye, John! ``` -## Export "as" +## Exportar "as" -The similar syntax exists for `export`. +Existe un sintáxis similar para `export`. -Let's export functions as `hi` and `bye`: +Exportemos funciones como `hi` y `bye`: ```js // 📁 say.js @@ -141,7 +144,7 @@ Let's export functions as `hi` and `bye`: export {sayHi as hi, sayBye as bye}; ``` -Now `hi` and `bye` are official names for outsiders, to be used in imports: +Ahora `hi` y `bye` son los nombres oficiales para desconocidos, a ser utilizados en importaciones: ```js // 📁 main.js @@ -153,95 +156,95 @@ say.*!*bye*/!*('John'); // Bye, John! ## Export default -In practice, there are mainly two kinds of modules. +En la práctica, existen principalmente dos tipos de módulos. -1. Modules that contain a library, pack of functions, like `say.js` above. -2. Modules that declare a single entity, e.g. a module `user.js` exports only `class User`. +1. Módulos que contienen una librería, paquete de funciones, como `say.js` de arriba. +2. Módulos que declaran una entidad simple, por ejemplo un módulo `user.js` exporta únicamente `class User`. -Mostly, the second approach is preferred, so that every "thing" resides in its own module. +Principalmente, se prefiere el segundo enfoque, de modo que cada "cosa" reside en su propio módulo. -Naturally, that requires a lot of files, as everything wants its own module, but that's not a problem at all. Actually, code navigation becomes easier if files are well-named and structured into folders. +Naturalmente, eso requiere muchos archivos, ya que todo quiere su propio módulo, pero eso no es un problema en absoluto. En realidad, la navegación de código se vuelve más fácil si los archivos están bien nombrados y estructurados en carpetas. -Modules provide a special `export default` ("the default export") syntax to make the "one thing per module" way look better. +Los módulos proporcionan una sintaxis especial 'export default' ("la exportación predeterminada") para que la forma de "una cosa por módulo" se vea mejor. -Put `export default` before the entity to export: +Poner `export default` antes de la entidad a exportar: ```js // 📁 user.js -export *!*default*/!* class User { // just add "default" +export *!*default*/!* class User { // sólo agregar "default" constructor(name) { this.name = name; } } ``` -There may be only one `export default` per file. +Sólo puede existir un sólo `export default` por archivo. + +...Y luego importarlo sin llaves: -...And then import it without curly braces: ```js // 📁 main.js -import *!*User*/!* from './user.js'; // not {User}, just User - +import *!*User*/!* from './user.js'; // no {User}, sólo User new User('John'); ``` -Imports without curly braces look nicer. A common mistake when starting to use modules is to forget curly braces at all. So, remember, `import` needs curly braces for named exports and doesn't need them for the default one. +Las importaciones sin llaves se ven mejor. Un error común al comenzar a usar módulos es olvidarse de las llaves. Entonces, recuerde, `import` necesita llaves para las exportaciones con nombre y no las necesita para la predeterminada. -| Named export | Default export | +| Export con nombre | Export predeterminada | |--------------|----------------| | `export class User {...}` | `export default class User {...}` | | `import {User} from ...` | `import User from ...`| -Technically, we may have both default and named exports in a single module, but in practice people usually don't mix them. A module has either named exports or the default one. +Técnicamente, podemos tener exportaciones predeterminadas y con nombre en un solo módulo, pero en la práctica la gente generalmente no las mezcla. Un módulo tiene exportaciones con nombre o la predeterminada. -As there may be at most one default export per file, the exported entity may have no name. +Como puede haber como máximo una exportación predeterminada por archivo, la entidad exportada puede no tener nombre. -For instance, these are all perfectly valid default exports: +Por ejemplo, todas estas son exportaciones predeterminadas perfectamente válidas: ```js -export default class { // no class name +export default class { // sin nombre de clase constructor() { ... } } ``` ```js -export default function(user) { // no function name +export default function(user) { // sin nombre de función alert(`Hello, ${user}!`); } ``` ```js -// export a single value, without making a variable +// exportar un único valor, sin crear una variable export default ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; ``` -Not giving a name is fine, because there is only one `export default` per file, so `import` without curly braces knows what to import. +No dar un nombre está bien, porque solo hay un "export default" por archivo, por lo que "import" sin llaves sabe qué importar. -Without `default`, such an export would give an error: +Sin `default`, dicha exportación daría un error: ```js -export class { // Error! (non-default export needs a name) +export class { // Error! (exportación no predeterminada necesita un nombre) constructor() {} } ``` -### The "default" name +### El nombre "default" -In some situations the `default` keyword is used to reference the default export. +En algunas situaciones, la palabra clave `default` se usa para hacer referencia a la exportación predeterminada. -For example, to export a function separately from its definition: +Por ejemplo, para exportar una función por separado de su definición: ```js function sayHi(user) { alert(`Hello, ${user}!`); } -// same as if we added "export default" before the function +// lo mismo que si agregamos "export default" antes de la función export {sayHi as default}; ``` -Or, another situation, let's say a module `user.js` exports one main "default" thing, and a few named ones (rarely the case, but it happens): +Otra situación, supongamos un módulo `user.js` exporta una cosa principal "default", y algunas cosas con nombre (raro el caso, pero sucede): ```js // 📁 user.js @@ -256,7 +259,7 @@ export function sayHi(user) { } ``` -Here's how to import the default export along with a named one: +Aquí la manera de importar la exportación predeterminada junto con la exportación con nombre: ```js // 📁 main.js @@ -265,38 +268,37 @@ import {*!*default as User*/!*, sayHi} from './user.js'; new User('John'); ``` -And, finally, if importing everything `*` as an object, then the `default` property is exactly the default export: +Y por último, si importamos todo `*` como un objeto, entonce la propiedad `default` es exactamente la exportación predeterminada: ```js // 📁 main.js import * as user from './user.js'; - -let User = user.default; // the default export +let User = user.default; // la exportación predeterminada new User('John'); ``` -### A word against default exports +### Unas palabras contra exportaciones predeterminadas -Named exports are explicit. They exactly name what they import, so we have that information from them; that's a good thing. +Las exportaciones con nombre son explícitas. Nombran exactamente lo que importan, así que tenemos esa información de ellos; Eso es bueno. -Named exports force us to use exactly the right name to import: +Las exportaciones con nombre nos obligan a usar exactamente el nombre correcto para importar: ```js import {User} from './user.js'; -// import {MyUser} won't work, the name must be {User} +// import {MyUser} no funcionará, el nombre debe ser {User} ``` -...While for a default export, we always choose the name when importing: +...Mientras que para una exporación predeterminada siempre elegimos el nombre al importar: ```js -import User from './user.js'; // works -import MyUser from './user.js'; // works too -// could be import Anything... and it'll still work +import User from './user.js'; // funciona +import MyUser from './user.js'; // también funciona +// puede ser import Cualquiera... y aun funcionaría ``` -So team members may use different names to import the same thing, and that's not good. +Por lo tanto, los miembros del equipo pueden usar diferentes nombres para importar lo mismo, y eso no es bueno. -Usually, to avoid that and keep the code consistent, there's a rule that imported variables should correspond to file names, e.g: +Por lo general, para evitar eso y mantener el código consistente, existe una regla que establece que las variables importadas deben corresponder a los nombres de los archivos, por ejemplo: ```js import User from './user.js'; @@ -305,25 +307,25 @@ import func from '/path/to/func.js'; ... ``` -Still, some teams consider it a serious drawback of default exports. So they prefer to always use named exports. Even if only a single thing is exported, it's still exported under a name, without `default`. +Aún 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, todavía se exporta con un nombre, sin `default`. -That also makes re-export (see below) a little bit easier. +Eso también hace que la reexportación (ver más abajo) sea un poco más fácil. -## Re-export +## Reexportación -"Re-export" syntax `export ... from ...` allows to import things and immediately export them (possibly under another name), like this: +La sintáxis "Reexportar" `export ... from ...` permite importar cosas e inmediatamente exportarlas (posiblemente bajo otro nombre), de esta manera: ```js -export {sayHi} from './say.js'; // re-export sayHi - -export {default as User} from './user.js'; // re-export default +export {sayHi} from './say.js'; // reexportar sayHi +export {default as User} from './user.js'; // reexportar default ``` -Why would that be needed? Let's see a practical use case. +¿Por qué se necesitaría eso? Veamos un caso de uso práctico. -Imagine, we're writing a "package": a folder with a lot of modules, with some of the functionality exported outside (tools like NPM allow us to publish and distribute such packages), and many modules are just "helpers", for internal use in other package modules. +Imagínese, estamos escribiendo un "paquete": una carpeta con muchos módulos, con algunas de las funciones exportadas al exterior (herramientas como NPM nos permiten publicar y distribuir dichos paquetes), y muchos módulos son solo "ayudantes", para uso interno en otros módulos de paquete. + +La estructura del archivo podría ser así: -The file structure could be like this: ``` auth/ index.js @@ -337,48 +339,46 @@ auth/ ... ``` -We'd like to expose the package functionality via a single entry point, the "main file" `auth/index.js`, to be used like this: +Nos gustaría exponer la funcionalidad del paquete a través de un único punto de entrada, el "archivo principal" `auth/index.js`, para ser utilizado así: ```js import {login, logout} from 'auth/index.js' ``` -The idea is that outsiders, developers who use our package, should not meddle with its internal structure, search for files inside our package folder. We export only what's necessary in `auth/index.js` and keep the rest hidden from prying eyes. +La idea es que los extraños, los desarrolladores que usan nuestro paquete, no deben entrometerse 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. -As the actual exported functionality is scattered among the package, we can import it into `auth/index.js` and export from it: +Como la funcionalidad real exportada se encuentra dispersa entre el paquete, podemos importarla en `auth/index.js` y exportar desde ella: ```js // 📁 auth/index.js - -// import login/logout and immediately export them +// importar login/logout e inmediatamente exportarlas import {login, logout} from './helpers.js'; export {login, logout}; - -// import default as User and export it +// importar default como User y exportarlo import User from './user.js'; export {User}; ... ``` -Now users of our package can `import {login} from "auth/index.js"`. +Ahora los usuarios de nuestro paquete pueden hacer esto `import {login} from "auth/index.js"`. -The syntax `export ... from ...` is just a shorter notation for such import-export: +La sintáxis `export ... from ...` es solo una notación más corta para tales importación-exportación: ```js // 📁 auth/index.js -// import login/logout and immediately export them +// importar login/logout e inmediatamente exportarlos export {login, logout} from './helpers.js'; -// import default as User and export it +// importar default como User y exportarlo export {default as User} from './user.js'; ... ``` -### Re-exporting the default export +### Reexportando la exportación predeterminada -The default export needs separate handling when re-exporting. +La exportación predeterminada necesita un manejo separado cuando se reexporta. -Let's say we have `user.js`, and we'd like to re-export class `User` from it: +Digamos que tenemos `user.js`, y nos gustaría volver a exportar la clase `User` de él: ```js // 📁 user.js @@ -387,69 +387,69 @@ export default class User { } ``` -1. `export User from './user.js'` won't work. What can go wrong?... But that's a syntax error! - To re-export the default export, we have to write `export {default as User}`, as in the example above. +1. `export User from './user.js'` no funcionará. Qué puede fallar?... Pero es un errro de sintáxis! + +Para reexportar la exportación predeterminada, tenemos que escribir `export {default as User}`, tal como en el ejemplo de arriba. -2. `export * from './user.js'` re-exports only named exports, but ignores the default one. +2. `export * from './user.js'` reexporta únicamente las exportaciones con nombre, pero ignora la exportación predeterminada. - If we'd like to re-export both named and the default export, then two statements are needed: +Si nos gustaría reexportar tanto la exportación con nombre como la predeterminada, se necesitan dos declaraciones: ```js - export * from './user.js'; // to re-export named exports - export {default} from './user.js'; // to re-export the default export + export * from './user.js'; // para reexportar exportaciones con nombre + export {default} from './user.js'; // para reexportar la exportación predeterminada ``` -Such oddities of re-exporting the default export are one of the reasons why some developers don't like them. +Tales rarezas de reexportar la exportación predeterminada son una de las razones por las que a algunos desarrolladores no les gustan. -## Summary +## Resumen -Here are all types of `export` that we covered in this and previous articles. +Aquí están todos los tipos de 'exportación' que cubrimos en este y en artículos anteriores. -You can check yourself by reading them and recalling what they mean: +Puede comprobarlo al leerlos y recordar lo que significan: -- Before declaration of a class/function/..: - - `export [default] class/function/variable ...` -- Standalone export: +- Antes de la declaración de clase/función/..: + - `export [default] clase/función/variable ...` +- Export independiente: - `export {x [as y], ...}`. -- Re-export: +- Reexportar: - `export {x [as y], ...} from "module"` - - `export * from "module"` (doesn't re-export default). - - `export {default [as y]} from "module"` (re-export default). + - `export * from "module"` (no reexporta la predeterminada). + - `export {default [as y]} from "module"` (reexporta la predeterminada). -Import: +Importación: -- Named exports from module: +- Exportación con nombre desde módulo: - `import {x [as y], ...} from "module"` -- Default export: +- Exportación predeterminada: - `import x from "module"` - `import {default as x} from "module"` -- Everything: +- Todo: - `import * as obj from "module"` -- Import the module (its code runs), but do not assign it to a variable: +- Importar el módulo (su código se ejecuta), pero no lo asigna a una variable: - `import "module"` -We can put `import/export` statements at the top or at the bottom of a script, that doesn't matter. +Podemos poner las declaraciones `import/export` en la parte superior o inferior de un script, eso no importa. + +Entonces, técnicamente este código está bien: -So, technically this code is fine: ```js sayHi(); - // ... - -import {sayHi} from './say.js'; // import at the end of the file +import {sayHi} from './say.js'; // import al final del archivo ``` -In practice imports are usually at the start of the file, but that's only for more convenience. +En la práctica, las importaciones generalmente se encuentran al comienzo del archivo, pero eso es solo para mayor comodidad. -**Please note that import/export statements don't work if inside `{...}`.** +**Tenga en cuenta que las declaraciones de import/export no funcionan si están dentro `{...}`.** -A conditional import, like this, won't work: +Una importación condicional, como esta, no funcionará: ```js if (something) { - import {sayHi} from "./say.js"; // Error: import must be at top level + import {sayHi} from "./say.js"; // Error: import debe estar en nivel superior } ``` -...But what if we really need to import something conditionally? Or at the right time? Like, load a module upon request, when it's really needed? +...Pero, ¿qué pasa si realmente necesitamos importar algo condicionalmente? O en el momento adecuado? Por ejemplo, ¿cargar un módulo a pedido, cuando realmente se necesita? -We'll see dynamic imports in the next article. +Veremos importaciones dinámicas en el próximo artículo.