ES6 import in for-of-loop - javascript

Is there any way to import and export multiple files using for-of-loop (or another loop) in ES6?
const moduleNames = ['NumberUtils', 'StringUtils', 'ArrayUtils', 'MyModule', 'AnotherModule', 'BaseModule']
let modules = {}
for (const moduleName of moduleNames) {
import module from './' + moduleName
modules.moduleName = module
}
export modules
Without loop I have to write:
import NumberUtils from './NumberUtils'
import StringUtils from './StringUtils'
import ArrayUtils from './ArrayUtils'
import MyModule from './MyModule'
import AnotherModule from './AnotherModule'
import BaseModule from './BaseModule'
export {
NumberUtils,
StringUtils
ArrayUtils
MyModule
AnotherModule
BaseModule
}

One of main features of ES modules is they can be statically analyzed. For this reason import statement follows strict syntax - so does export. A snippet 'without loop' is the way it has to be done.
This allows to figure out module imports and exports exactly in IDEs and tools. This is useful for tree-shaking, for instance.

I think that better and more clear way to do it is to create an index file and then import multiple components in one import.
//index.js
import PopUp from './PopUp';
import ToggleSwitch from './ToggleSwitch';
export {
PopUp,
ToggleSwitch
};
//app.js
import { PopUp, ToggleSwitch } from './components';

For multiple import files I found this solution:
const files = require.context('../myFolder', true, /(Module|Utils)\.js$/)

Related

Why do npm modules, like material-ui, export es6 and es5 files?

In many npm modules I recently installed (eg. #material-ui/core) there are three ways to import the same React component:
import { AppBar } from '#material-ui/core'
import AppBar from '#material-ui/core/AppBar/AppBar'
import AppBar from '#material-ui/core/es/AppBar/AppBar'
In which scenario should I use variant 3 / es6 exported files?
If tree-shaking / dead code elimination works in webpack and the npm module. Should I rather use variant 1 (named import) instead of variant 2 (default export)?
There are two types of export:
1) Named export that is you export something like:
// exports a function declared earlier
export { myFunction };
// exports a constant
export const FOO = "foo";
if you want to import these, then syntax would be like:
import {FOO, myFunction} from './file';
2) Default export that is you export something like:
export default function() {}
you can rename your function, class to any name you want when you import, and its syntax would be like:
import myFunction from './file';
NOTE: You can have multiple named export in single file but you can not have multiple default export in single file.
For more detail check out this link: https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export
The main difference is how that library is exporting the modules.
When you do import AppBar from '#material-ui/core/AppBar/AppBar', this means that #material-ui/core/AppBar/AppBar is exporting a single object with export default AppBar.
And you're expected to imported as you did. However you're not limited to export a single default export from your module.
For example with React exposes the main object (i.e. React which is again being exported as default) that has all the properties you may want to use. But with the import syntax from ES6, you can import a specific property/function from that module(e.g. import { Component } from 'react'; which is exported as export class Component...)
I hope that's clear!

Import object contained in another object

I want to do something like this, but using import rather than require:
const MySubmodule = require('react-native').MyModule.MySubmodule;
I tried:
import { MySubmodule } from 'react-native/MyModule';
import { MySubmodule } from ('react-native').MyModule;
import { MySubmodule } from 'react-native'.MyModule;
None of these works.
So any idea how to import a module contained in another using import?
You will have to import MyModule completely, and can then separately destructure it to get the parts you are interested in:
import {MyModule} from 'react-native';
const {MySubmodule} = MyModule;
The import statement does not support directly destructuring exports. See also this Babel issue for some more info.

what is the difference between import Task and import { Task } in es6

What is the difference between
import { Tasks } from '../api/tasks.js';
and
import Task from './Task.jsx';
when to use {} and when to not use {} ?
(by the way, this is from meteor tutorial https://www.meteor.com/tutorials/react/update-and-remove)
You don't have to use the {} when you precise that it's a default export.
For example :
export default class Test{}
You can do :
import Test from './test'
In the other hand, if you don't precise "default" keyword, you have to precise {} :
export class Test {}
gives
import { Test } from './test'
when you do
import { Tasks } from '../api/tasks.js';
you are importing Task module from '../api/tasks.js';
when you do
import Tasks from '../api/tasks.js';
you are importing default export module from '../api/tasks.js'; Here Task is a variable which is referring default export module.
Example.
task.js
export default Task;
case 1: It is Task from task.js
case 2: It is Task variable pointing to Task module in task.js that is Task
if I do
import someVariable from './api/task.js' still it will work because someVarible will point to default export module that is Task module in task.js
If I do
import {someVariable} from './api/task.js' it will search for module someVariable in task.js but it is not there so now it is undefined.
if you want to grab the all modules you can do
import * as test from "Test";
If you exporting only some modules and not all then you have to specify wictch module you want
import { Module1, Module2, Module3 } from "Modules"; //grab only given in {}
if you have only export default Test you can to
import "Test";
read more about modules

ES2015: Named import translation

I'm following ES2015. I want to translate regular javascript import statements to ES2015 import statement(s).
What I have:
I have javascript import line as below:
var db = require('../config').get('db')
What I've tried:
import { config } from '../config'
const db = config.db
NOTE
config folder has the index.js which I want to load. In the regular var ... = require('...') statement automatically loads index.js if exists. And I want the ES2015 script also automatically loads when imported.
I think what you're looking for is:
import { db } from '../config'
Assuming db is properly export-ed from config.js, that should work.
Just to clarify, there's three main kinds of imports in JS native modules:
Import the whole module:
import * as foo from 'path/to/foo';
const something = foo.something;
Import specific named exports of the module. This works if the module exports the appropriate objects using export statements:
import { something } from 'path/to/foo';
Import the default export of the module. This only works if the module has an export default statement in it:
import thedefaultexport from 'path/to/foo';
It looks like the '../config' module exports a single object with a get() method. If this is the case, import the whole module, like so:
import * as config from '../config';
And get the database like so:
const db = config.get('db');
If possible, you might want to refactor your '../config' module so that it exports db directly.
export {db};
And then you can use the syntax #AsadSaeeduddin suggested:
import {dp} from '../config';

Difference between import X and import * as X in node.js (ES6 / Babel)?

I have a node.js library lib written in ES6 (compiled with Babel) in which I export the following submodules:
"use strict";
import * as _config from './config';
import * as _db from './db';
import * as _storage from './storage';
export var config = _config;
export var db = _db;
export var storage = _storage;
If from my main project I include the library like this
import * as lib from 'lib';
console.log(lib);
I can see the proper output and it work as expected { config: ... }. However, if I try to include the library like this:
import lib from 'lib';
console.log(lib);
it will be undefined.
Can someone explain what is happening here? Aren't the two import methods supposed to be equivalent? If not, what difference am I missing?
import * as lib from 'lib';
is asking for an object with all of the named exports of 'lib'.
export var config = _config;
export var db = _db;
export var storage = _storage;
are named exports, which is why you end up with an object like you did.
import lib from 'lib';
is asking for the default export of lib.
e.g.
export default 4;
would make lib === 4. It does not fetch the named exports. To get an object from the default export, you'd have to explicitly do
export default {
config: _config,
db: _db,
storage: _storage
};
Just adding to Logan's solution because understanding import with brackets, * and without solved a problem for me.
import * as lib from 'lib';
is the equivalent of:
import {config, db, storage} as lib from 'lib';
Where the * is similar to a wildcard that imports all of the export var from lib.
export var config;
export var db;
export var storage;
Alternatively, using:
import lib from 'lib';
Allows you to only access the default export:
// lib.js
export default storage;
Using {} also only imports specific components from the module, which reduces the footprint with bundlers like Webpack.
While:
import storage, { config, db } from './lib'
would import all modules including export default storage;
See Dan Abramov's answer:
When should I use curly braces for ES6 import?
import X from Y; is a syntax sugar.
import lib from 'lib';
is equal to
import { default as lib } from 'lib';

Categories