How to export and destructure an object? - javascript

I have reducer keys
const foo = {
ADD: 1,
REDO: 2,
UNDO: 3,
}
And I want to export it but when importing, I should be able to do
import MyComponent, { ADD, REDO } from '../bar'
The only problem is that I already another thing to export
Here is what my code looks like
export default Component
export { Bar, ...foo} // can't do this, gives me syntax error

export { Bar, ...foo} // can't do this, gives me syntax error
Yes, that is a syntax error. Exports need names so you must do something like the following:
export Bar;
export foo;
But this requires you to import foo:
import { foo } from '../bar'
If you want to import ADD, REDO etc they must be their own named objects:
export const ADD = 1;
export const REDO = 2;
export const UNDO = 3;

Related

Javascript export default and import

I have the following code:
const API1 = new API({
...
})
const API2 = new API({
...
})
export default { API1, API2 }
I need to import like this:
import API1 from '/lib/api'
API1.get()...
But it doesn't work.
I don't want to do this:
import blah from '/lib/api'
blah.API1.get()...
How can I solve this ?
Thanks.
If you need to export multiple items, and don't want to have to create two variables in the consuming module (one for the default import - the object, and another for the API1 property), your only other option is to change the default export to a named export, allowing you to import just one particular named property:
const API1 = new API({
...
})
const API2 = new API({
...
})
export { API1, API2 }
and
import { API1 } from '/lib/api'
API1.get()...
The export { syntax indicates that the export is named, rather than default, and the import { syntax indicates that you're importing a named import, rather than a default import.
(It looks a lot like destructuring, and it's a little bit similar, but it's not the same)
Since you're default exporting an object you need to access individual property to access there methods, Instead you can use named exports
// exporting values
export const API1 = new API({
...
})
export const API2 = new API({
...
})
// Importing values
import { API1 } from '/lib/api'
API1.get()...

rewrite module.exports into export default but preserve possibility to import single entity

Is it possible to achieve same functionality as:
module.exports = {
a: 1,
b: 2
}
...which later allows:
import { a } from 'path/to/module'
by using ES6 modules like (or export default):
export const moduleName = {
a: 1,
b: 2
}
so that later rather than importing whole module into other one, only part of it will be imported
Use named exports instead:
export const a = 1;
export const b = 2;
Note that although this allows the consumer to do something like import { a } from ..., you're now not actually destructuring an object with an a property there, like you were doing originally with the module.exports syntax, you're just extracting the named export.
You can still export a default object in addition to using named exports, if you wanted:
export default { c: 'c', d: 'd' }
and then you can import with
import obj from '...';
const { c } = obj;

Correct way to export object in es6 module

I'm trying to export an my module as an object but exporting it seems an 'anti pattern' (https://medium.com/#rauschma/note-that-default-exporting-objects-is-usually-an-anti-pattern-if-you-want-to-export-the-cf674423ac38)
So I was wondering what's the correct way to export an object and then use it as
import utils from "./utils"
`
utils.foo()
Currently I'm doing like so
/** a.js **/
function foo(){
//...
}
export {
foo
}
/** b.js **/
import * as utils from "a";
utils.foo()
is it correct like so? Do I maintain the tree-shaking feature?
thanks
If the object you want to import/export only contains some functions (as I assume due to the Utils name), you can export the functions separately as follows:
export function doStuff1() {}
export function doStuff2() {}
And import like this:
import {doStuff1, doStuff2} from "./myModule";
However, if the object you want to export holds state in addition to methods, you should stick to a simple export default myObject. Otherwise, calling the imported methods won't work as intended, since the context of the object is lost.
As an example, the following object should be exported as a whole, since the properties of the object should stay encapsulated. Only importing and calling the increment function would not mutate myObject since the context of the object cannot be provided (since it's not imported as a whole).
const myObject = {
counter: 0,
increment: function() {
this.counter++;
}
}
export default myObject;
es6 native way to do this:
// file1.es6
export const myFunc = (param) => {
doStuff(param)
}
export const otherFunc = ({ param = {} }) => {
doSomething({ ...param })
}
// file2.es6
import { otherFunc } from './file1.es6'
import * as MyLib from './file1.es6'
MyLib.myfunc(0)
MyLib.otherFunc({ who: 'Repley' })
otherFunc({ var1: { a1: 1 } })
And so on.

Importing specific objects from "export default" results in "undefined"

I'm learning Webpack and therefore testing out some different methods I've observed.
I've created the following JS file, which was a method for exporting I observed in a NPM package.
// test.js
const Foo = { myVar: "Foo" }
const Bar = { myVar: "Bar"}
export default {
Foo,
Bar
}
And inside my app.js I write the following:
// app.js
import { Foo } from './test'
console.log(Foo);
I was expecting that I would get the Foo object from my exported object in test.js but I just get an undefined in the console. Also, Webpack says:
"export 'Foo' was not found in './test'
So, removing the the curly brackets from the import:
// app.js
import Temp from './test'
console.log(Temp);
This produces an object, containing the Foo and Bar objects.
What is wrong and right here?
Remove the default keyword, that's for specifying what your default export is, not for all your exports. You're currently saying that your entire object of exports is the default.
export {
Foo,
Bar
}
The default is for saying if something wasn't specified, this should be the default, e.g:
export {
Foo as default, // import WhateverIWantToCallIt from './test'
Foo, // import { Foo } from './test'
Bar // import { Bar } from './test'
}
// Or you can export things separately:
export function Bar() {...}
export function Foo() {...}
export default Foo; // Declare what the default is
You actually export an object with two parameters:
module.exports = {Foo, Bar}
If you want to use import {Foo} from './file' syntax you should export your constants separately
export const Foo = { myVar: "Foo" }
export const Bar = { myVar: "Bar"}
I think you are confusing destructering with named imports
//this is not destructing but named imports
import { Foo } from './test'
// this is default export.
export default { Foo, Bar }
in order to use named imports you have to use named exports .
as other comments has already explained you have to use
export without default
// test.js
const Foo = { myVar: "Foo" }
const Bar = { myVar: "Bar"}
export default {
Foo,
Bar
}
// app.js
import { Foo } from './test'
console.log(Foo); // works as expected

Failing to import properties of a module

I have a module A that is like
const defaults = {
something: {...},
somethingElse : {...}
}
export { defaults as default };
And then I am importing like
import * as mod, { something } from 'moduleA';
mod is correctly an object that has the two declared properties, but { something } is undefined.
Any idea what can be the reason?
[With the module as in the question] I am importing like
import * as mod, { something } from 'moduleA';
but something is undefined
But you don't have an export with the name something in your module. There only is a default-export that contains an object. You would need to do
import mod from 'moduleA';
const { something } = mod;
I have a module A that is like
const defaults = {
something: {...},
somethingElse : {...}
}
export { defaults as default };
But you really shouldn't do that anyway. Exporting "singleton" objects that act like a namespace is an antipattern in ES6 modules. You should use named exports instead:
export const something = {...};
export const somethingElse = {...};
With this, your original attempt at importing the module would have worked.
If you want to be able to access named exports in your import, you have to export them directly:
const defaults = {
something: {...},
somethingElse : {...}
}
export {
defaults as default,
defaults.something as something,
defaults.somethingElse as somethingElse
};
Alternatively you could use destructuring for the export of something and somethingElse:
export const { something, somethingElse} = defaults;
And then import it like you did:
import * as mod, { something } from 'moduleA';
But: mod will now contain the props: defaults, something, somethingElse.
If you only wont the default (which equals your defaults):
import mod, { something } from 'moduleA';
You can learn more about the ES6 import and export syntax in Axel Rauschmayr's great blog post:
http://www.2ality.com/2014/09/es6-modules-final.html
import * as mod, { something } from 'moduleA';
The reason something is undefined is because when you: export { defaults as default }; you're exporting a member called default. When you export {apple, banana} you export a member apple and a member banana.
When you import something without specifying the members you want to import you import the member named default. When you do specify the members you wish to import, of course, you import those.
This is why although your code doesn't do what you intend, the following will:
const mod = { something: 'test'};
export { mod as default }; // same as export default mod;
and
import mod, {default as test} from './index'; // test and mod both have the same values
console.log(mod); // { something: 'test' }
console.log(test.something); // test
something is not exported from your module A, only the object defaults is.
So, to get something, you need to take it from what you imported.
import * as mod from 'moduleA';
const something = mod.something;
If you want to be able to import something like this : import {something} from 'moduleA', you will need to export it explicitely. For example:
export const something = {};
const somethingElse = {};
export default const defaults = {
something,
somethingElse
};

Categories

Resources