ES6 eksportuje wszystkie wartości z obiektu

112

Powiedzmy, że mam moduł ( ./my-module.js), który ma obiekt, który powinien być jego wartością zwracaną:

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

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

Więc mogę je zaimportować na przykład:

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

Jedyny sposób, jaki znalazłem, to zakodowanie eksportu:

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

Co nie jest dynamiczne.

Czy można wyeksportować wszystkie wartości z obiektu?

mauvm
źródło
6
Nie, ponieważ wartości obliczanej dynamicznie nie można wyeksportować statycznie.
Bergi
@Bergi, zastanawiam się, czy w jakiś sposób można ustawić wartości statyczne. Zastanawiałem się, co jeśli użyjesz interface { a: number, b: number, c: number }? Teoretycznie powinno to być możliwe, prawda?
Fleuv
1
@Fleuv export const {a, b, c} = valuesto właśnie składnia deklarująca ten statyczny interfejs
Bergi

Odpowiedzi:

39

Nie wydaje się. Cytat z modułów ECMAScript 6: ostateczna składnia :

Możesz się zastanawiać - dlaczego potrzebujemy nazwanych eksportów, jeśli moglibyśmy po prostu eksportować obiekty (takie jak CommonJS)? Odpowiedź jest taka, że ​​nie można wymusić statycznej struktury za pomocą obiektów i stracić wszystkich związanych z nią korzyści (opisanych w następnej sekcji).

Joel Richard
źródło
3
Czy możesz użyć tablicy, jeśli mają one pary nazwa-wartość?
Kevin Suttle
79

Naprawdę nie mogę polecić obejścia tego rozwiązania, ale działa. Zamiast eksportować obiekt, możesz użyć nazwanego eksportu każdego członka. W innym pliku zaimportuj nazwane eksporty pierwszego modułu do obiektu i wyeksportuj ten obiekt jako domyślny. Wyeksportuj również wszystkie nazwane eksporty z pierwszego modułu za pomocąexport * from './file1';

wartości / wartość.js

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

export {a, b, c};

wartości / 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
źródło
2
Dlaczego nie poleciłbyś tego?
jsdario,
2
Może dlatego, że lekarstwo jest gorsze niż choroba (chyba że piszesz bibliotekę do użytku publicznego i jesteś naprawdę wybredny, jeśli chodzi o import)?
machineghost
Tak, to dobre podsumowanie. To technika, której użyłem kiedyś w bibliotece, aby ułatwić zużycie. Myślę, że lepiej byłoby zarządzać eksportami w ramach jednego pliku, nawet jeśli jest to więcej pracy dla autora biblioteki. Rezultatem jest o jedną mniejszą głębokość modułu dla użytkownika.
ryanjduffy
Całkiem podoba mi się to obejście, ale powinno to być „./value” zamiast „./values” w values ​​/ index.js, prawda?
Jan Paepke
1
Naprawdę nie sądzę, aby to była odpowiedź, ponieważ jeśli już eksportuję { a, b, c }, dlaczego muszę ponownie eksportować? Prawdziwe pytanie brzmi: co, jeśli mam tylko const obj = { a, b, c }i czy mogę wyeksportować wszystkie składowe obj? Myślę, że odpowiedź brzmi NIE.
windmaomao
14

wypróbuj to brzydkie, ale wykonalne rozwiązanie:

// 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
źródło
12

Po prostu musiałem to zrobić dla pliku konfiguracyjnego.

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

export default config;

Możesz to zrobić w ten sposób

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

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

To jest używanie maszynopisu.

mikeysee
źródło
34
Powinieneś być w stanie to zrobićimport config from './config';
Matt Hamann
4
export const a = 1;
export const b = 2;
export const c = 3;

To zadziała z dzisiejszymi transformacjami Babel i powinno wykorzystać wszystkie zalety modułów ES2016, ilekroć ta funkcja faktycznie pojawi się w przeglądarce.

Możesz także dodać, export default {a, b, c};co pozwoli zaimportować wszystkie wartości jako obiekt bez * as, tjimport myModule from 'my-module';

Źródła:

Jon z
źródło
3

Proponuję co następuje, spodziewajmy się module.js :

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

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

a potem możesz zrobić w pliku 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

Więcej przykładów niszczących obiektów: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destruecting_assignment#Object_destruecting

RiZKiT
źródło
3

Każda odpowiedź wymaga zmiany instrukcji importu.

Jeśli chcesz móc korzystać z:

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

jak w pytaniu, aw swoim my-modulemasz wszystko, czego potrzebujesz do wyeksportowania w jednym obiekcie (co może być przydatne np. jeśli chcesz zweryfikować wyeksportowane wartości za pomocą schematu Joi lub JSON) to my-modulemusiałbyś być albo:

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

Lub:

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

Niezbyt ładne, ale kompiluje się do tego, czego potrzebujesz.

Zobacz: przykład Babel

rsp
źródło
3

Z javascriptem można zrobić wiele głupich rzeczy. Zostawię ten cytat z książki YDKJS.

wprowadź opis obrazu tutaj

Wspomniana strona książki ->

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&lpg=PT150&dq=JS+engine+cannot+statically+analyze+the+contents+of+plain+object&source=bl&ots=7v8fMUgwhP3&sWIYvig=Hvig=hldk X & ved = 2ahUKEwi4qseXyrDdAhUS-6QKHZYTAEQQ6AEwAHoECAEQAQ # v = onepage & q = JS% 20engine% 20cannot% 20statically% 20analyze% 20the% 20contents% 20of% 20plain% 20object & f = false

localhoost
źródło
2

Eksportowanie każdej zmiennej z pliku zmiennych. Następnie zaimportowanie ich z * tak jak w innym pliku i wyeksportowanie jako stałej z tego pliku da ci dynamiczny obiekt z nazwanymi eksportami z pierwszego pliku będącymi atrybutami obiektu wyeksportowanego z drugiego.

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
źródło
Czy możesz również dodać wyjaśnienie?
Nilambar Sharma