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.
Related
I'd like to make clear one thing.
In React, we often use import {useState, useEffect} from 'react'.
Can we think of this as a destructuring feature in ES6?
Nope.
It's not like object destructuring but it is actually importing named exports.
To be more clear, it's just importing a module exported as useState.
No, they are different.
While they look similar (and probably import was designed to look like destructuring), they don't behave the same way. To set that clear, importing uses a slightly different syntax: uses the as keyword for import renaming instead of the : familiar from destructuring.
These differences are because of how the module system works. Other differences are:
imported variables cannot be assigned to by the importer module, however...
the exported variables can be changed anytime by the exporter, and that will also be reflected by the importers' variables, and that implies, that...
it's not possible to nest import renaming, like how it would be possible via destructuring:
import {foo as {bar as baz}} from './module';
//is invalid, as is:
import {foo as {bar: baz}} from './module';
//...while:
const {foo: {bar: baz}} = value;
//is valid.
as the module system is static (like variables), it's not possible to import a dynamic key or use the rest syntax (all imports are known before evaluating the code).
Looking at react src code
export {
useState,
// ...
Children,
// ....
} from './src/React';
so you can import directly from this object e.g.
import { useState } from 'react'
// you can also rename it to anything you want
import { useState as useReactState } from 'react'
or you can get the whole object as exported as default and then reference its useState
import React from 'react'
// use React.useState
// renaming will be like assigning a function to another variable e.g.
const useReactState = React.useState
// you also get all exported types and modules and wrap them up in React name
import * as React from 'react'
Babel transpiled outputs
import React from 'react'
const Component = () => {
const [state, setState] = React.useState()
}
// will transpile to something like
var Component = function Component() {
var _React$useState = _react["default"].useState(),
_React$useState2 = _slicedToArray(_React$useState, 2),
state = _React$useState2[0],
setState = _React$useState2[1];
};
On the other hand
import {useState} from 'react'
const Component = () => {
const [state, setState] = useState()
}
// will transpile to something like
var Component = function Component() {
var _useState = (0, _react.useState)(),
_useState2 = _slicedToArray(_useState, 2),
state = _useState2[0],
setState = _useState2[1];
};
There are some similarities between object destruction and import/export statement, but they are not the same at the end both have their own specific features different with the other
ES6 in-depth |
Export Statement |
Import Statement
I'm trying this:
import { each,find,filter,map,some,debounce,defer,delay,throttle,uniq,assign,extend,merge,omit,without,findIndex,compact,replace,groupBy,max,uniqueId } from '../npm_components/node_modules/lodash/lodash';
The resulting file, seems to be the same size as for example I import only this:
import { delay } from '../npm_components/node_modules/lodash/lodash';
Why?
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!
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$/)
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';