ES2015: Named import translation - javascript

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';

Related

How do you find out which functions are exported by a node/npm package?

Following my earlier question, and the Mozilla documentation on import, I now understand that I must do something like the following to use the functionality in a module:
import * as name from "module"; or
import {functionName} from "module";
Coming from using CommonJS, I never thought about which functions were exported by a package because I just used to require them like:
const vueServerRenderer = require('vue-server-renderer') // get the module
vueServerRenderer.createRenderer() // use a function in that module
How can someone find out which functions are being exported by a module such as express or vueServerRenderer so I know how to use the correct import statement like:
import express from 'express' instead of import * as express from 'express'?
You need to read the module source.
Every export statement exports something. It may be a function, an array, a string, a class etc.
Every export statement without default needs to be destructured on import:
import { NonDefaultThing1, NonDefaultThing2 } from 'somewhere'
An export statement with default must be imported directly without the {}:
import DefaultThing from 'somewhere'
Some modules have default export but also non-default exports. You can pick and choose what to import:
import DefaultThing, { NonDefaultThing7 } from 'somewhere'
If you use an IDE that can parse javascript such as Microsoft Visual Studio Code you can get autocompletion/intellisense of the import statement. There are even plugins that does auto-import: just use a class or function or something from a module and it will automatically add the required import statement at the top of your file.
TLDR: The default export.
Say a particular library named "module" has the following code
function functionName() {
// function body
}
export default functionName;
Now, in your code, if you put
import blah from "module";
then blah will point to functionName.

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.

ES6 import in for-of-loop

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$/)

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