ES6 exporta todos los valores del objeto

112

Digamos que tengo un módulo ( ./my-module.js) que tiene un objeto que debería ser su valor de retorno:

let values = { a: 1, b: 2, c: 3 }

// "export values" results in SyntaxError: Unexpected token

Entonces puedo importarlos como:

import {a} from './my-module'           // a === 1
import * as myModule from './my-module' // myModule.a === 1

La única forma que encontré es codificando las exportaciones:

export let a = values.a
export let b = values.b
export let c = values.c
// or:
export let {a, b, c} = values

Que no es dinámico.

¿Es posible exportar todos los valores de un objeto?

mauvm
fuente
6
No, porque el valor calculado dinámicamente no se puede exportar estáticamente.
Bergi
@Bergi, me pregunto si de alguna manera es posible hacer que los valores sean estáticos de alguna manera. Estaba pensando en ¿qué pasa si usas un interface { a: number, b: number, c: number }? Teóricamente debería ser posible, ¿verdad?
Fleuv
1
@Fleuv export const {a, b, c} = valueses precisamente la sintaxis para declarar esa interfaz estática
Bergi

Respuestas:

39

No lo parece. Cita de los módulos ECMAScript 6: la sintaxis final :

Quizás se esté preguntando: ¿por qué necesitamos exportaciones con nombre si simplemente podríamos exportar objetos por defecto (como CommonJS)? La respuesta es que no puede hacer cumplir una estructura estática a través de objetos y perder todas las ventajas asociadas (descritas en la siguiente sección).

Joel Richard
fuente
3
¿Podrías usar una matriz si tienen pares nombre-valor?
Kevin Suttle
79

Realmente no puedo recomendar esta solución alternativa , pero funciona. En lugar de exportar un objeto, utiliza exportaciones con nombre para cada miembro. En otro archivo, importe las exportaciones con nombre del primer módulo a un objeto y exporte ese objeto como predeterminado. También exporte todas las exportaciones nombradas desde el primer módulo usandoexport * from './file1';

valores / valor.js

let a = 1;
let b = 2;
let c = 3;

export {a, b, c};

valores / index.js

import * as values from './value';

export default values;
export * from './value';

index.js

import values, {a} from './values';

console.log(values, a); // {a: 1, b: 2, c: 3} 1
Ryanjduffy
fuente
2
¿Por qué no recomendarías esto?
jsdario
2
¿Quizás porque la cura es peor que la enfermedad (a menos que esté escribiendo una biblioteca de consumo público y sea muy exigente con la importación)?
machineghost
Sí, ese es un buen resumen. Es una técnica que usé una vez en la biblioteca para facilitar el consumo. Creo que sería mejor administrar las exportaciones dentro de un solo archivo, aunque es más trabajo para el autor de la biblioteca. El resultado es una profundidad de módulo menos para el usuario.
ryanjduffy
Me gusta bastante esta solución alternativa, pero debería ser './value' en lugar de './values' en values ​​/ index.js, ¿verdad?
Jan Paepke
1
Realmente no creo que esta sea la respuesta, ya que si ya exporto { a, b, c }, ¿por qué necesito exportar nuevamente? La verdadera pregunta es ¿qué pasa si solo tengo const obj = { a, b, c }y puedo exportar todos los miembros de obj? Supongo que la respuesta es NO.
windmaomao
14

prueba esta solución fea pero viable:

// use CommonJS to export all keys
module.exports = { a: 1, b: 2, c: 3 };

// import by key
import { a, b, c } from 'commonjs-style-module';
console.log(a, b, c);
resorte
fuente
12

Solo necesitaba hacer esto para un archivo de configuración.

var config = {
    x: "CHANGE_ME",
    y: "CHANGE_ME",
    z: "CHANGE_ME"
}

export default config;

Puedes hacerlo así

import { default as config } from "./config";

console.log(config.x); // CHANGE_ME

Esto está usando TypeScript, eso sí.

mikeysee
fuente
34
Deberías poder hacerloimport config from './config';
Matt Hamann
4
export const a = 1;
export const b = 2;
export const c = 3;

Esto funcionará con las transformaciones de Babel hoy y debería aprovechar todos los beneficios de los módulos ES2016 siempre que esa característica llegue a un navegador.

También puede agregar lo export default {a, b, c};que le permitirá importar todos los valores como un objeto sin * as, es decirimport myModule from 'my-module';

Fuentes:

Jon z
fuente
3

Sugiero lo siguiente, esperemos un module.js :

const values = { a: 1, b: 2, c: 3 };

export { values }; // you could use default, but I'm specific here

y luego puedes hacer en un index.js :

import { values } from "module";

// directly access the object
console.log(values.a); // 1

// object destructuring
const { a, b, c } = values; 
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3

// selective object destructering with renaming
const { a:k, c:m } = values;
console.log(k); // 1
console.log(m); // 3

// selective object destructering with renaming and default value
const { a:x, b:y, d:z = 0 } = values;
console.log(x); // 1
console.log(y); // 2
console.log(z); // 0

Más ejemplos de destrucción de objetos: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring

RiZKiT
fuente
3

Cada respuesta requiere cambiar las declaraciones de importación.

Si quieres poder usar:

import {a} from './my-module'           // a === 1
import * as myModule from './my-module' // myModule.a === 1

como en la pregunta, y en su my-moduletiene todo lo que necesita para exportar en un objeto (que puede ser útil, por ejemplo, si desea validar los valores exportados con Joi o JSON Schema), entonces my-moduletendría que ser:

let values = { a: 1, b: 2, c: 3 }
let {a, b, c} = values;
export {a, b, c};

O:

let values = { a: 1, b: 2, c: 3 }
export let {a, b, c} = values;

No es bonito, pero se adapta a lo que necesita.

Ver: ejemplo de Babel

rsp
fuente
2

Exportando cada variable de su archivo de variables. Luego, importarlos con * como en su otro archivo y exportarlos como una constante desde ese archivo le dará un objeto dinámico con las exportaciones nombradas del primer archivo como atributos del objeto exportado desde el segundo.

Variables.js

export const var1 = 'first';
export const var2 = 'second':
...
export const varN = 'nth';

Other.js

import * as vars from './Variables';

export const Variables = vars;

Third.js

import { Variables } from './Other';

Variables.var2 === 'second'
Tanya Randstoft
fuente
¿Puede agregar una explicación también?
Nilambar Sharma