ES6 экспортирует все значения из объекта

112

Скажем, у меня есть module ( ./my-module.js), у которого есть объект, который должен быть его возвращаемым значением:

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

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

Поэтому я могу импортировать их, например:

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

Единственный способ, который я нашел, - это жестко закодировать экспорт:

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

Что не динамично.

Можно ли экспортировать все значения из объекта?

Mauvm
источник
6
Нет, потому что динамически вычисленное значение нельзя экспортировать статически.
Берги
@Bergi, мне интересно, можно ли каким-то образом сделать значения статичными. Я думал о том, что, если вы используете interface { a: number, b: number, c: number }? Теоретически это должно быть возможно, правда?
Fleuv
1
@Fleuv export const {a, b, c} = values- это как раз синтаксис для объявления этого статического интерфейса
Берги

Ответы:

39

Не похоже. Цитата из модулей ECMAScript 6: последний синтаксис :

Вы можете спросить - зачем нам именованный экспорт, если мы можем просто экспортировать объекты по умолчанию (например, CommonJS)? Ответ заключается в том, что вы не можете навязать статическую структуру с помощью объектов и потерять все связанные с ней преимущества (описанные в следующем разделе).

Джоэл Ричард
источник
3
Могли бы вы использовать массив, если у них есть пары имя-значение?
Кевин Саттл
79

Я не могу рекомендовать это решение, но оно работает. Вместо экспорта объекта вы используете именованный экспорт каждого члена. В другом файле импортируйте именованный экспорт первого модуля в объект и экспортируйте этот объект по умолчанию. Также экспортируйте все названные экспорты из первого модуля, используяexport * from './file1';

значения / значение.js

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

export {a, b, c};

значения / 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
источник
2
Почему бы вам не порекомендовать это?
jsdario 08
2
Может быть, потому, что лекарство хуже, чем болезнь (если вы не пишете общедоступную библиотеку и действительно разборчивы в том, как ее импортировать)?
machineghost
Да, это хорошее резюме. Это метод, который я однажды использовал в библиотеке, чтобы упростить использование. Я думаю, что было бы лучше управлять экспортом в одном файле, даже если это больше работы для автора библиотеки. В результате для пользователя на один модуль меньше.
ryanjduffy
Мне очень нравится этот обходной путь, но в values ​​/ index.js должно быть './value' вместо './values', верно?
Ян Пэпке
1
Я действительно не думаю, что это ответ, так как если я уже экспортирую { a, b, c }, зачем мне экспортировать снова? Настоящий вопрос в том, что, если у меня есть только const obj = { a, b, c }и могу ли я экспортировать все члены obj? Думаю, ответ - НЕТ.
windmaomao
14

попробуйте это уродливое, но работоспособное решение:

// 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
источник
12

Мне просто нужно было сделать это для файла конфигурации.

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

export default config;

Вы можете сделать это так

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

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

Имейте в виду, что это использует Typescript.

Mikeysee
источник
34
Вы должны уметь это делатьimport config from './config';
Мэтт Хаманн
4
export const a = 1;
export const b = 2;
export const c = 3;

Это будет работать с преобразованиями Babel сегодня и должно использовать все преимущества модулей ES2016 всякий раз, когда эта функция действительно появляется в браузере.

Вы также можете добавить, export default {a, b, c};что позволит вам импортировать все значения как объект без * as, т.е.import myModule from 'my-module';

Источники:

Джон З
источник
3

Я предлагаю следующее, давайте ждать module.js :

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

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

а затем вы можете сделать в 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

Дополнительные примеры деструктуризации объектов: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring

РиЗКиТ
источник
3

Каждый ответ требует изменения операторов импорта.

Если вы хотите иметь возможность использовать:

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

как в вопросе, и в вашем у my-moduleвас есть все, что вам нужно экспортировать в одном объекте (что может быть полезно, например, если вы хотите проверить экспортированные значения с помощью Joi или JSON Schema), тогда вам my-moduleнужно будет либо:

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

Или:

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

Не очень красиво, но он компилируется в соответствии с вашими потребностями.

См .: Пример Babel

rsp
источник
3

С javascript можно делать много глупостей. Я оставлю здесь эту цитату из книги YDKJS.

введите описание изображения здесь

Упомянутая страница книги ->

https://books.google.com.tr/books?id=iOc6CwAAQBAJ&pg=PT150&lpg=PT150&dq=JS+engine+cannot+static+analyze+the+contents+of+plain+object&source=bl&ots=7v8fW&fMUgxyz_sig=ru&hl=en X & ved = 2ahUKEwi4qseXyrDdAhUS-6QKHZYTAEQQ6AEwAHoECAEQAQ # v = onepage & q = JS% 20engine% 20cannot% 20static% 20analyze% 20the% 20contents% 20of% 20plain% 20object & f = false

местный
источник
2

Экспорт каждой переменной из вашего файла переменных. Затем их импорт с *, как в другом файле, и экспорт в виде константы из этого файла даст вам динамический объект с именованным экспортом из первого файла, который является атрибутами объекта, экспортированного из второго.

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'
Таня Рэндстофт
источник
Не могли бы вы также добавить пояснения?
Ниламбар Шарма