import and export of modules in ES6 - javascript

I am in the process of refactoring my structure of import and export of modules. The goal here is to import UserActions through index.js, in multiple files (namely, in UserReducer.js and Home.js).
the project's tree structure looks like:
js
|_ modules
| |_ user
| | |_index.js
| | |_UserActions.js
| | |_UserReducer.js
| | |_UserSagas.js
|_ containers
| |_ Home.js
This is the content of modules/user/index.js:
import * as UserActions from './UserActions'
import * as UserSagas from './UserSagas'
import UserReducer from './UserReducer'
export { UserActions, UserReducer, UserSagas }
Initially the actions were being imported directly from the UserActions file, in both UserReducer.js and Home.js as follows:
in UserReducer.js: import * as UserActions from './UserActions'
in Home.js: import * as UserActions from 'modules/user/UserActions'
And everything was working correctly. Now I want these two imports to use the index.js file above.
step 1)
inside UserReducer, i change the import line from:
import * as UserActions from './UserActions'
to:
import { UserActions } from '.' // fetches the named export from index.js
This is working.
step 2)
inside Home.js, i change the import line from:
import * as UserActions from 'modules/user/UserActions'
to:
import { UserAction } from 'modules/user'
Now webpack doesn't complain but the browser throws error in UserReducer, that UserActions is undefined.
Finally:
using the import { UserActions } from 'path_to_index.js' notation works, as long as I use it in one place only (could be in either file).
As soon as I use it in both places, all hell breaks loose...
Any ideas? Thanks
Edit: I realize that the errors above occur only if the user/index.js imports and exports UserSagas as well. If I import the UserSagas directly from their file instead of adding it to index.js, the app runs correctly.

Turns out #estus is correct in that even importing another exported part from index.js would cause circular dependency.
I wanted index.js to be the unique interface to users, but it looks like that will only apply to components outside of "users". Internally, the import will be directly from the actions file

Related

Group all files in import statements and export statement in ES6

I have these three files - tabs, routes, urls in a folder called config
Folder structure
config
| - urls
| - tabs
| - routes
Here's what I tried so far. Created an index.js file in config folder where I could write all the export statements.
export * from './routes'
export * from './urls'
export * from './tabs'
I want to nest all the files like below in import statement and use them wherever needed in other .js files
import {tabs, routes, urls } from '../config'
How do I group all the files in one single import statement. Could anyone please help?
Is this what you're looking for?
config/index.js
export * as routes from './routes'
export * as urls from './urls'
export * as tabs from './tabs'
Use import *
import * from '../config/';
I was able to do it this way. But, is there a better way?
import routes from './routes';
import urls from './urls';
import tabs from './tabs';
export { routes, tabs, urls };
And, I'm calling it like this
import {tabs, routes, urls } from '../config'

reexport all files from a folder webpack

We're using a folder structure like this
components
| Button.js
| Nav.js
| ...etc
| index.js
somefolder
|somefile.js
in the inderx file we're importing every component and reexporting it like this
// index.js
import Button from './Button'
import Nav from './Nav'
export {Button, Nav}
this way we can import many components into a file like this
// somefile.js
import {Button, Nav} from '../components'
Maintaining that index file is a bit of a pain though and discourages flexible use of components. I know that Webpack can import many files with a syntax like this
function requireAll(r) { r.keys().forEach(r); }
requireAll(require.context('./components/', true, /\.js$/));
however, I didn't yet find a way to reexport all of these components to use them like above.
The desired outcome is to replace the index.js file with something that automates the process of bundling all the files from a folder without having to add every file manually.
I think getting rid of the file index will not be the best solution and may cause questions from other developers. But I can offer a slightly more simplified way:
index.js:
export * from './some-component1.js';
export * from './some-component2.js';
some-component1.js:
export {SomeComponent1};
some-component2.js:
export {SomeComponent2};

What does import * do in Javascript?

I was browsing through this repo on Github and was trying to comprehend the working of the code
Here, the author (or programmer) have mentioned import * at multiple places so I am trying to comprehend and understand how import * work?
First in Game.js file of his repo he have mentioned/written like this
import * as actions from '../actions';
In VS Code, when if I click on '../actions using command It is redirecting me to this file -> index.js
then in Index.js they have something like this
import * as ActionTypes from './action-types';
when I click on ./action-types it redirects me to here action-types.js
I went through firefox docs but I wasn't able to clearly make sense for the first example like for one, the action folder contains multiple files and how does import * as actions from '../actions'; mean index.js file
While i get he have called/referenced the functions using actions.functionName() or ActionType.TypeName
My Prime question remains
how does import * as actions from '../actions'; mean index.js file ?
The import * as name syntax imports all exported content of a javascript file.
For example, if you want to import an entire module's contents, then access the doAllTheAmazingThings() function
import * as myModule from '/modules/my-module.js';
myModule.doAllTheAmazingThings();
From the docs
Import in js is new syntax of ES6 to import a module it has the same work of require but its easier to filter what do you want in a module
In your example you import * as actions from '../actions'; you import all function from ../actions file
its same to do const actions = require('../actions')
but its easier to manage what you want
this syntax is not work on all browser so be sure to use transpiler with babel or other
you can see this syntax in python too
When you reference a directory in an import statement, it looks and loads the index.js file in that directory. What I usually do there is export classes and functions under that directory in a grouped object, so they can be easily accessed:
For instance in index.js I export sth like:
{
Class1,
method1
}
where each is imported as such:
import Class1 from './Class1';
So they just group the classes/methods/... that are in files in the directory.
Then you can easily access it as such:
import { Class1, method1 } from './mymodule';
vs
import Class1 from './mymodule/Class1';

How to import everything from a module in react using es6?

I am using brace which is a npm module for theming in ace editor.
Currently, I am importing each theme using
import 'brace/theme/solarized_dark';
How do I import all the themes as I need to give the user the option to pick any theme.
Create one brace/themes/index.js and export the things that you want to acess
export * as theme1 from './theme1';
export * as theme2 from './theme2';
....
Then import from that folder : (name is index.js so no need to give full path to the file)
import * as SolDark 'brace/themes'; // by default get index.js
Then you can access each method like :
SolDark.theme1;
SolDark.theme2;
I don't know how does your file structure look like, but lets assume it is something like that
|brace
|---theme
| |---theme1
| |---theme2
| | ...
| |---solarized_dark
Then you could create index.js in the theme folder and inside it:
//index.js
export {default as theme1} from './theme1';
export {default as theme2} from './theme2';
assuming you have default exports.
Then in other files you just simply do:
//other_file.js
import {theme1, theme2} from 'someRelativePath/brace/theme/index'
or
import * as themes from 'someRelativePath/brace/theme/index'

Organizing React Components

I am building a React App which consists of lot of smaller components. At present I am importing the components in app.js like this:
import Nav from './components/nav'
import ColorPicker from './components/colorPicker'
class App extends Component {
render() {
return (
<div>
<Nav />
<ColorPicker />
</div>
);
}
}
export default App;
Each component is a separate js file (nav.js, colorPicker.js). Is there anyway to just import everything in components folder so I don't have to explicitly specify importing of the components.
I'm not sure if there is a way to just import everything from a folder with one module per file, but you can make a kind of index.js file in which you would import everything that you will want, then:
export * from nav;
export * from colorPicker;
And then you only have to import your one index file from which you can: import {nav, colorPicker} from './components/things';
You always have to explicitly set the import of the components you use, but what you can do is decrease the amount of code typed by setting up an index file where you export all components you want to make available in said file, like this for example:
./components/index.js
import Component1 from './Component1';
import Component2 from './Component2';
import Component3 from './Component3';
export {
Component1,
Component2,
Component3,
};
Then import the needed components in the desired file like this:
./app.js
import { Component1, Component2 } from './components';
class App extends Component {
render() {
return (
<div>
<Nav />
<ColorPicker />
</div>
);
}
}
export default App;
Tree structure
app.js
components
+---
Component1.js
Component2.js
index.js
If you can add a babel plugin, you can use babel-plugin-wildcard, that is a plugin that makes exactly what you want.
Taken from NPM:
With the following folder structure:
|- index.js
|- dir
|- a.js
|- b.js
|- c.js
the following JS:
import * as Items from './dir';
will be compiled to:
const Items = {};
import _wcImport from "./dir/a";
Items.A = _wcImport;
import _wcImport1 from "./dir/b";
Items.B = _wcImport1;
import _wcImport2 from "./dir/c";
Items.C = _wcImport2;
meaning you will be able to access the items using Items.A and Items.B.
You can also selectively choose files using:
import { A, C } from "dir/*";
which in the above example would convert to:
import A from "./dir/a";
import C from "./dir/c";
The above is like doing:
import * as temp from "dir";
const { A, C } = temp;
Answer found inside this post.

Categories

Resources