ES6 exporte toutes les valeurs de l'objet

112

Disons que j'ai un module ( ./my-module.js) qui a un objet qui devrait être sa valeur de retour:

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

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

Je peux donc les importer comme:

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

Le seul moyen que j'ai trouvé est de coder en dur les exportations:

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

Ce qui n'est pas dynamique.

Est-il possible d'exporter toutes les valeurs d'un objet?

Mauvm
la source
6
Non, car la valeur calculée dynamiquement ne peut pas être exportée statiquement.
Bergi
@Bergi, je me demande s'il est possible de rendre les valeurs statiques d'une manière ou d'une autre. Je pensais à et si vous utilisiez un interface { a: number, b: number, c: number }? Théoriquement, cela devrait être possible, non?
Fleuv
1
@Fleuv export const {a, b, c} = valuesest précisément la syntaxe pour déclarer cette interface statique
Bergi

Réponses:

39

Cela ne semble pas. Citation des modules ECMAScript 6: la syntaxe finale :

Vous vous demandez peut-être pourquoi avons-nous besoin d'exportations nommées si nous pouvions simplement exporter des objets par défaut (comme CommonJS)? La réponse est que vous ne pouvez pas appliquer une structure statique via des objets et perdre tous les avantages associés (décrits dans la section suivante).

Joël Richard
la source
3
Pourriez-vous utiliser un tableau s'ils ont des paires nom-valeur?
Kevin Suttle
79

Je ne peux pas vraiment recommander cette solution de contournement, mais elle fonctionne. Plutôt que d'exporter un objet, vous utilisez des exportations nommées de chaque membre. Dans un autre fichier, importez les exportations nommées du premier module dans un objet et exportez cet objet par défaut. Exportez également toutes les exportations nommées du premier module en utilisantexport * from './file1';

values ​​/ value.js

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

export {a, b, c};

values ​​/ 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
la source
2
Pourquoi ne recommanderiez-vous pas cela?
jsdario
2
Peut-être parce que le remède est pire que la maladie (à moins que vous n'écriviez une bibliothèque publique et que vous soyez vraiment pointilleux sur la façon dont elle est importée)?
machineghost du
Oui, c'est un bon résumé. C'est une technique que j'ai utilisée une fois en bibliothèque pour faciliter la consommation. Je pense qu'il serait préférable de gérer les exportations dans un seul fichier même si c'est plus de travail pour l'auteur de la bibliothèque. Le résultat est une profondeur de module en moins pour l'utilisateur.
ryanjduffy
J'aime assez cette solution de contournement, mais elle devrait être «./value» au lieu de «./values» dans values ​​/ index.js, non?
Jan Paepke
1
Je ne pense vraiment pas que ce soit la réponse, car si j'exporte déjà { a, b, c }, pourquoi dois-je exporter à nouveau? La vraie question est: que se passe-t-il si je n'ai const obj = { a, b, c }et puis-je exporter tous les membres des obj? Je suppose que la réponse est NON.
windmaomao
14

essayez cette solution laide mais réalisable:

// 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);
printemps
la source
12

J'avais juste besoin de le faire pour un fichier de configuration.

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

export default config;

Tu peux le faire comme ça

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

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

Ceci est en utilisant Typescript, pensez-vous.

Mikeysee
la source
34
Vous devriez pouvoir le faireimport config from './config';
Matt Hamann
4
export const a = 1;
export const b = 2;
export const c = 3;

Cela fonctionnera avec les transformations Babel aujourd'hui et devrait profiter de tous les avantages des modules ES2016 chaque fois que cette fonctionnalité atterrit dans un navigateur.

Vous pouvez également ajouter export default {a, b, c};ce qui vous permettra d'importer toutes les valeurs en tant qu'objet sans le * as, ieimport myModule from 'my-module';

Sources:

Jon z
la source
3

Je suggère ce qui suit, attendons un module.js :

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

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

et puis vous pouvez faire dans 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

Plus d'exemples d'objets de destruction: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring

RiZKiT
la source
3

Chaque réponse nécessite la modification des instructions d'importation.

Si vous souhaitez pouvoir utiliser:

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

comme dans la question, et dans votre my-modulevous avez tout ce dont vous avez besoin pour exporter dans un seul objet (ce qui peut être utile par exemple si vous voulez valider les valeurs exportées avec Joi ou JSON Schema) alors votre my-moduledevrait être soit:

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;

Pas joli, mais il compile ce dont vous avez besoin.

Voir: l' exemple de Babel

rsp
la source
3

Vous pouvez faire beaucoup de choses stupides avec javascript. Je laisserai ici cette citation du livre YDKJS.

entrez la description de l'image ici

Page du livre mentionnée ->

https://books.google.com.tr/books?id=iOc6CwAAQBAJ&pg=PT150&lpg=PT150&dq=JS+engine+cannot+stately+analyze+the+contents+of+plain+object&source=bl&ots=7v8fMUgwhxBko&pYWaXP3&pYWaXko&pYWaXko3 X & ved = 2ahUKEwi4qseXyrDdAhUS-6QKHZYTAEQQ6AEwAHoECAEQAQ # v = onepage & q = JS% 20engine% 20cannot% 20statiquement% 20analyze% 20the% 20contents% 20of% 20plain% 20object & f = false

localhoost
la source
2

Exporter chaque variable de votre fichier de variables. Ensuite, les importer avec * comme dans votre autre fichier et les exporter en tant que constante à partir de ce fichier vous donnera un objet dynamique avec les exportations nommées du premier fichier étant des attributs sur l'objet exporté à partir du second.

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
la source
Pouvez-vous s'il vous plaît ajouter une explication?
Nilambar Sharma