ES6 mengekspor semua nilai dari objek

112

Katakanlah saya memiliki modul ( ./my-module.js) yang memiliki objek yang seharusnya menjadi nilai kembaliannya:

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

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

Jadi saya bisa mengimpornya seperti:

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

Satu-satunya cara yang saya temukan adalah dengan melakukan hard coding pada ekspor:

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

Yang tidak dinamis.

Apakah mungkin untuk mengekspor semua nilai dari suatu objek?

mauvm.dll
sumber
6
Tidak, karena nilai yang dihitung secara dinamis tidak dapat diekspor secara statis.
Bergi
@Bergi, saya bertanya-tanya apakah mungkin untuk membuat nilai statis di suatu tempat. Saya berpikir tentang bagaimana jika Anda menggunakan interface { a: number, b: number, c: number }? Secara teoritis seharusnya mungkin, bukan?
Fleuv
1
@Fleuv export const {a, b, c} = valuesadalah sintaks yang tepat untuk mendeklarasikan antarmuka statis
Bergi

Jawaban:

39

Sepertinya tidak. Kutipan dari modul ECMAScript 6: sintaks terakhir :

Anda mungkin bertanya-tanya - mengapa kita membutuhkan ekspor bernama jika kita dapat secara sederhana mengekspor objek (seperti CommonJS)? Jawabannya adalah Anda tidak dapat menerapkan struktur statis melalui objek dan kehilangan semua keuntungan terkait (dijelaskan di bagian selanjutnya).

Joel Richard
sumber
3
Bisakah Anda menggunakan array jika mereka memiliki pasangan nama-nilai?
Kevin Suttle
79

Saya tidak dapat merekomendasikan solusi ini untuk mengatasi masalah tetapi berfungsi. Daripada mengekspor objek, Anda menggunakan ekspor bernama setiap anggota. Di file lain, impor ekspor bernama modul pertama ke dalam objek dan ekspor objek itu sebagai default. Juga ekspor semua ekspor bernama dari modul pertama menggunakanexport * from './file1';

nilai / nilai js

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

export {a, b, c};

nilai / 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
sumber
2
Mengapa Anda tidak merekomendasikan ini?
jsdario
2
Mungkin karena obatnya lebih buruk daripada penyakitnya (kecuali jika Anda menulis perpustakaan yang dapat dikonsumsi publik dan Anda benar-benar pilih-pilih tentang bagaimana cara mengimpornya)?
machineghost
Ya, itu ringkasan yang bagus. Ini adalah teknik yang saya gunakan sekali di perpustakaan untuk memudahkan konsumsi. Saya pikir akan lebih baik untuk mengelola ekspor dalam satu file meskipun lebih banyak pekerjaan untuk penulis perpustakaan. Hasilnya adalah kedalaman modul yang berkurang satu untuk pengguna.
ryanjduffy
Saya cukup suka solusi ini, tetapi seharusnya './value' bukan './values' di values ​​/ index.js, bukan?
Jan Paepke
1
Saya rasa ini bukan jawabannya, karena kalau saya sudah mengekspor { a, b, c }, mengapa saya perlu mengekspor lagi? Pertanyaan sebenarnya adalah bagaimana jika saya hanya punyaconst obj = { a, b, c } dan dapatkah saya mengekspor obj semua anggota? Saya kira jawabannya TIDAK.
windmaomao
14

coba solusi jelek tapi bisa diterapkan ini:

// 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
sumber
12

Saya hanya perlu melakukan ini untuk file konfigurasi.

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

export default config;

Anda bisa melakukannya seperti ini

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

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

Ini menggunakan Ketikan pikiran Anda.

mikeysee
sumber
34
Anda harus dapat melakukannyaimport config from './config';
Matt Hamann
4
export const a = 1;
export const b = 2;
export const c = 3;

Ini akan berfungsi dengan transformasi Babel hari ini dan harus memanfaatkan semua manfaat modul ES2016 setiap kali fitur itu benar-benar masuk ke browser.

Anda juga dapat menambahkan export default {a, b, c};yang akan memungkinkan Anda untuk mengimpor semua nilai sebagai objek tanpa * as, yaituimport myModule from 'my-module';

Sumber:

Jon z
sumber
3

Saya menyarankan yang berikut, mari kita harapkan module.js :

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

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

dan kemudian Anda bisa melakukannya di 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

Contoh lainnya dari objek yang merusak: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring

RiZKiT
sumber
3

Setiap jawaban membutuhkan perubahan pernyataan impor.

Jika Anda ingin dapat menggunakan:

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

seperti dalam pertanyaan, dan dalam diri Anda, my-moduleAnda memiliki semua yang Anda butuhkan untuk diekspor dalam satu objek (yang dapat berguna misalnya jika Anda ingin memvalidasi nilai yang diekspor dengan Joi atau JSON Schema) maka Anda my-moduleharus:

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

Atau:

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

Tidak cantik, tetapi mengkompilasi sesuai kebutuhan Anda.

Lihat: Contoh Babel

rsp
sumber
3

Anda dapat melakukan banyak hal bodoh dengan javascript. Saya akan meninggalkan kutipan ini di sini dari buku YDKJS.

masukkan deskripsi gambar di sini

Halaman buku yang disebutkan ->

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=7v8fMUgwhz&sig=dO=en&pvIX X & ved = 2ahUKEwi4qseXyrDdAhUS-6QKHZYTAEQQ6AEwAHoECAEQAQ # v = onepage & q = JS% 20engine% 20cannot% 20statically% 20analyze% 20the% 20contents% 20of% 20plain% 20object & f = false

localhoost
sumber
2

Mengekspor setiap variabel dari file variabel Anda. Kemudian mengimpornya dengan * seperti pada file Anda yang lain dan mengekspornya sebagai konstanta dari file itu akan memberi Anda objek dinamis dengan ekspor bernama dari file pertama menjadi atribut pada objek yang diekspor dari yang kedua.

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
sumber
Bisakah Anda juga menambahkan penjelasan?
Nilambar Sharma