ES6 exporta todos os valores do objeto

112

Digamos que eu tenha um módulo ( ./my-module.js) que tem um objeto que deve ser seu valor de retorno:

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

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

Então posso importá-los como:

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

A única maneira que encontrei é codificando as exportações:

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

O que não é dinâmico.

É possível exportar todos os valores de um objeto?

Mauvm
fonte
6
Não, porque o valor calculado dinamicamente não pode ser exportado estaticamente.
Bergi
@Bergi, estou pensando se é possível tornar os valores estáticos de alguma forma. Eu estava pensando sobre e se você usar um interface { a: number, b: number, c: number }? Teoricamente, deveria ser possível, certo?
Fleuv
1
@Fleuv export const {a, b, c} = valuesé precisamente a sintaxe para declarar essa interface estática
Bergi

Respostas:

39

Não parece. Citação dos módulos ECMAScript 6: a sintaxe final :

Você pode estar se perguntando - por que precisamos de exportações nomeadas se poderíamos simplesmente exportar objetos padrão (como CommonJS)? A resposta é que você não pode impor uma estrutura estática por meio de objetos e perder todas as vantagens associadas (descritas na próxima seção).

Joel richard
fonte
3
Você poderia usar uma matriz se eles tivessem pares nome-valor?
Kevin Suttle
79

Eu realmente não posso recomendar esta solução alternativa , mas ela funciona. Em vez de exportar um objeto, você usa exportações nomeadas de cada membro. Em outro arquivo, importe as exportações nomeadas do primeiro módulo para um objeto e exporte esse objeto como padrão. Também exporte todas as exportações nomeadas do primeiro 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
fonte
2
Por que você não recomendaria isso?
jsdario
2
Talvez porque a cura seja pior do que a doença (a menos que você esteja escrevendo uma biblioteca de consumo público e seja realmente exigente sobre como importá-la)?
machineghost
Sim, é um bom resumo. É uma técnica que usei uma vez na biblioteca para facilitar o consumo. Acho que seria melhor gerenciar as exportações em um único arquivo, embora isso seja mais trabalhoso para o autor da biblioteca. O resultado é um módulo a menos para o usuário.
ryanjduffy
Eu gosto bastante dessa solução alternativa, mas deve ser './value' em vez de './values' em values ​​/ index.js, certo?
Jan Paepke
1
Eu realmente não acho que essa seja a resposta, pois se eu já exporto { a, b, c }, por que devo exportar novamente? A verdadeira questão é e se eu apenas tiver const obj = { a, b, c }e puder exportar todos os membros do obj? Acho que a resposta é NÃO.
windmaomao
14

tente esta solução feia, mas viável:

// 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);
springuper
fonte
12

Eu só precisava fazer isso para um arquivo de configuração.

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

export default config;

Você pode fazer assim

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

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

Isso é usar o texto digitado, veja bem.

Mikeysee
fonte
34
Você deve ser capaz de fazerimport config from './config';
Matt Hamann
4
export const a = 1;
export const b = 2;
export const c = 3;

Isso funcionará com as transformações do Babel hoje e deve aproveitar todos os benefícios dos módulos ES2016 sempre que esse recurso realmente chegar a um navegador.

Você também pode adicionar o export default {a, b, c};que permitirá que você importe todos os valores como um objeto sem o * as, ou seja,import myModule from 'my-module';

Fontes:

Jon z
fonte
3

Eu sugiro o seguinte, vamos esperar um module.js :

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

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

e então você pode fazer em um 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

Mais exemplos de objetos destrutivos: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring

RiZKiT
fonte
3

Cada resposta requer alteração das declarações de importação.

Se você deseja ser capaz de usar:

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

como na pergunta, e na sua my-modulevocê tem tudo o que precisa para exportar em um objeto (o que pode ser útil, por exemplo, se você deseja validar os valores exportados com Joi ou esquema JSON), então você my-moduledeve ser:

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

Ou:

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

Não é bonito, mas compila o que você precisa.

Veja: Exemplo de Babel

rsp
fonte
3

Você pode fazer muitas coisas estúpidas com javascript. Vou deixar esta citação aqui do livro YDKJS.

insira a descrição da imagem aqui

Página mencionada do livro ->

https://books.google.com.tr/books?id=iOc6CwAAQBAJ&pg=PT150&lpg=PT150&dq=JS+engine+cannot+statically+analyze+the+contents+of+plain+object&source=bl&ots=7v8fMUgwhx&sig=dPhl3&sigWaX=vBydp3&sig=dPhl3 X & ved = 2ahUKEwi4qseXyrDdAhUS-6QKHZYTAEQQ6AEwAHoECAEQAQ # v = uma página & q = JS% 20engine% 20cannot% 20statically% 20analyze% 20the% 20contents% 20of% 20plain% 20object & f = false

localhoost
fonte
2

Exportando cada variável de seu arquivo de variáveis. Em seguida, importá-los com * como em seu outro arquivo e exportar o como uma constante desse arquivo fornecerá um objeto dinâmico com as exportações nomeadas do primeiro arquivo sendo atributos do objeto exportado do 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
fonte
Você também pode adicionar uma explicação?
Nilambar Sharma