Importing CommonJS does not destructure correctly in ES6 - javascript

In the root of my module dependency I have a file called form.js:
module.exports = require("./dist/bundle.js").form;
In my project I have:
import { someComponent } from 'my-dependency/form';
Yet someComponent will be undefined.
If I do this:
import form from 'my-dependency/form';
console.log(form.someComponent);
It will output something that looks like this in the console:
ƒ Rr(e){var t=e.component,n=void 0===t?"input":t,r=e.rend[....]
Yet, if I do this, it will work:
import form from 'my-dependency/form';
const { someComponent } = form;
What am I doing wrong here and how might I achieve what I want?
Inside of my src/form.js file I have:
import someComponent from "./someComponent";
export default {
someComponent
};
Inside of src/index.js, I have:
import * as form from "./form";
export default {
form
};
Probable root cause but not sure how to fix?...
It looks like the problem caused by exporting with CommonJS and importing using the ES6 syntax.
Here is someone with a similar issue but from 4 years ago:
https://github.com/google/traceur-compiler/issues/1483
and, from 2 years ago:
https://github.com/Microsoft/TypeScript/issues/11179
I've tried explicitly setting code like so but this did not seem to achieve what I want (creates a module with a default property):
Object.defineProperty(module.exports, "__esModule", {
value: true
});
It looks like reading online people will do import * as whatever from '..' but shouldn't destructuring work too?...

Two ways, either:
export const someComponent
Then:
import { someComponent } from 'my-dependency/form'
Or:
export default {
someComponent
}
Then:
import someComponent from 'my-dependency/form'

Related

export components from index file

i have shared components folder when i created some components and i want to export all of them to index.js file and then export all of them from that file. thats how it looks from one of the components file:
export default ToggleSwitch;
now in the index file i try to export them again, it looks like this:
export { default as ToggleSwitch } from './ToggleSwitch';
export { default as Input } from './TextField';
export { default as Button } from './Button';
when i try to import one of the components if i import like this:
import Button from '../../shared/components';
i get this error saying that '../../shared/components' does not contain a default export
and when i try to import it like this,
import { Button } from '../../shared/components';
i get error saying Button is not exported from '../../shared/components'.
what am i doing wrong here?
Have you tried importing as import { Button } from 'shared/components';?
For reference, the current codebase I work with has a similar structure for stores (flux stores) and this pattern works.
An example from the codebase: import { ClickStore } from 'stores';.

JS `import` is undefined, potentially circular import issue?

Preface
I'm using create-react-app to generate an application.
Problem
TodoList === undefined
Code
components/index.js
export { default as App } from './App/App.js';
export { default as TodoList } from './TodoList/TodoList.js';
containers/index.js
export { default as VisibleTodoList } from './VisibleTodoList.js';
components/App/App.js
import { VisibleTodoList } from '../../containers/index.js';
containers/VisibleTodoList.js
import { TodoList } from '../components/index.js';
components/TodoList/TodoList.js
export default function TodoList({ todos, onTodoClick }) { ... }
TodoList is now undefined. I believe it may have something to do with the fact that I have some sort of circular issue.
The thing is, if inside containers/VisibleTodoList.js I import using the following method, everything works fine.
import TodoList from '../components/TodoList/TodoList.js';
What is so special that breaks the import, if I try to import using a 'middleman' (the components/index.js file).
Full code
I have created a CodeSandbox that contains my full code, as it stands in my application. The application is pretty simplistic, but more complicated than I have outlined here.
https://codesandbox.io/s/m54nql1ky9
The problem is caused by the order of exports in your components/index.js file.
export { default as App } from './App/App.js';
export { default as TodoList } from './TodoList/TodoList.js';
Since App.js imports VisibleTodoList which needs to import TodoList and pass it to the redux connect function before it can export itself, you end up with a conflict.
I'm not sure if this is a implementation quirk of babel, or if this is a logical result from how the ES import spec is defined.
In any case, changing the order of exports fixes the bug.
export { default as TodoList } from './TodoList/TodoList.js';
export { default as App } from './App/App.js';
As a rule of thumb, if you can't refactor your files to avoid the import loop, you should put the outer layer component last in the list, since it might rely on imports higher up in the list.
Full working codesandbox here: https://codesandbox.io/s/74mlwnwyy1

React: Understanding import statement

What is the difference between these two statements
import React from 'react';
and
import React, { Component } from 'react';
Shouldn't import React from 'react' import everything including the content? What should I read to understand this?
You can read about this here.
Importing something without curly braces imports whatever was defined as the default export in the module from which you are importing. There can only be exactly one (or no) default export in a module.
foo.js:
const myObject = {foo: 'bar'};
export default myObject;
bar.js:
import theObject from './foo';
console.log(theObject);
// prints {foo: 'bar'}
// note that default exports are not named and can be imported with another name
Importing with curly braces imports what was exported as a named export with that name by the module. There can be multiple named exports in a module.
foo.js:
export const myObject = {foo: 'bar'};
export const anotherObject = {bar: 'baz'};
bar.js:
import {myObject, anotherObject, theObject} from './foo';
console.log(myObject);
// prints {foo: 'bar'}
console.log(anotherObject);
// prints {bar: 'baz'}
console.log(theObject);
// prints undefined
// because nothing named "theObject" was exported from foo.js
With
import React, { Component } from 'react';
you can do
class Menu extends Component { /* ... */ }
instead of
class Menu extends React.Component { /* ... */ }
from this: Import React vs React, { Component }
This is the ES6.
import Raect, { Component } from 'react';
Like
import default_export, { named_export } from 'react';
Consider two file. Person.js like
const person = {
name: 'johon doe'
}
export default person; // default export
Utility.js like
export const clean = () => { ... } //named export using const keyword
export const baseData = 10; //named export using const keyword
inport in App.js file. like
import person from './Person';
import prs from './Person';
import {clean} from './Utility';
import {baseData} from './Utility';
import {data as baseData} from './Utility';
import {* as bundled} from './Utility';
//bundled.baseData
//bundled.clean
João Belo posted a great answer to read, but I'll add one more thing. the second instance is using destructuring and object-shorthand to grab the 'Component' property's value from the react module and assign it to a 'Component' variable that you can use locally. If you don't know about destructuring and object-shorthand, you should definitely look them up. They come in handy.
Primarily, this boils down to the way you export variables. I believe, this must be a deliberate design decision from Facebook contributors.
export default class ReactExample {}
export class ComponentExample {}
export class ComponentExampleTwo {}
in the above example, ReactExample can be imported without using {}, where as the ComponentExample, ComponentExampleTwo , you have to import using {} statements.
The best way to understand is going through the source code.
React export source code
React Component source code
import * as myCode from './../../myCode';
This inserts myCode into the current scope, containing all the exports from the module in the file located in ./../../myCode.
import React, { Component } from 'react';
class myComponent extends Component { ... }
By Using above syntax your bundler ( e.g : webpack) will still bundle the ENTIRE dependency but since the Component module is imported in such a way using { } into the namespace, we can just reference it with Componentinstead of React.Component.
For more information you can read mozilla ES6 module docs.

Export default was not found

I have a Vue 2 project, and I've written a simple function for translating months in dates, which I would like to import in one of my components, but I'm getting an error:
export 'default' (imported as 'translateDate') was not found in '#/utils/date-translation'
The relative file path from the src folder is correct, and I am exporting the function like this:
export function translateDate(date) {
// my code
}
And then I am importing it in the component like this:
import translateDate from '#/utils/date-translation'
What am I doing wrong?
You have to specify default explicitly:
export default function translateDate(date) {
..
}
Either specify default as mentioned above, or if you're trying to export multiple items from the same file you need to import them with curly brackets.
So you would have:
export function doWork(){}
export const myVariable = true;
And then you'd import them in a separate file as:
import { doWork, myVariable} from "./myES6Module"
In my case I had to remove '{' and '}' arround the imported component :
import { CustomComponent } from './CustomComponent';
with
import CustomComponent from './CustomComponent';
Maybe you have two files with the same name.For example, "test.vue" and "test.js"
You need to set symlink setting in vue.config.js
config.resolve.symlinks(false);
Rather than using
export function translateDate(date) {
// my code
}
use
function translateDate(date){
//code
}
export default translateDate;
it worked for me...

Export multiple wrapper functions in Javascript ES6

I'm using react-komposer to wrap React components with a data fetching wrapper.
It is very basic and I'd want to wrap multiple components in Meteor. But I can't figure out what the export pattern is?
Here is what I have (and gives me an "Unexpected Token" error - probably obvious if you understand this well!):
// myContainer.jsx
import Component1 from './Component1.jsx';
import Component2 from './Component2.jsx';
function composer(props, onData) {
if (Meteor.subscribe('SingleTodoLists').ready()) {
const todoList = todoLists.find({}).fetch();
onData(null, { todoList });
}
}
export composeWithTracker(composer, Loading)(Component1);
export composeWithTracker(composer, Loading)(Component2);
And I'd like to import them like this:
import { Component1, Component2 } from './myContainer.jsx';
This wrapper syntax is not really clear for me, so I'm unsure about what to try. Playing with export default and other variations yielded no result so far.
If you don't use default exports, you need to name the things you export:
export const TrackedComponent1 = composeWithTracker(composer, Loading)(Component1);
export const TrackedComponent2 = composeWithTracker(composer, Loading)(Component2);
If you use default export instead you can omit the name, e.g.
export default composeWithTracker(composer, Loading)(Component1);
But you can only define one default export per module
See the documentation for the ES6 export syntax: https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export
Update:
If you want to keep the original export names:
import _Component1 from './Component1.jsx';
import _Component2 from './Component2.jsx';
//... you code here
export composeWithTracker(composer, Loading)(_Component1);
export composeWithTracker(composer, Loading)(_Component2);
Because Component1.jsx uses a default exports, when you import it you can rename it as you want (e.g. _Component1, UntrackedComponent1, ...). Without a default export, you could have used import { Component1 } as _Component1 instead.

Categories

Resources