Immediate ES6 export (React, Webpack, Babel) - reactjs

At the root of a directory (e.g. components/, containers/), I have an index.jsx file which immediately exports out all components, so that I can import them like so:
import {SampleOne, SampleTwo} from '../components'.
However, the root index.jsx file doesn't work with the following:
import SampleOne from './SampleOne/SampleOne';
import SampleTwo from './Sample/SampleTwo';
export default {
SampleOne,
SampleTwo
};
So, I converted it to the following (which is basically the same):
export {default as SampleOne} from './SampleOne/SampleOne';
export {default as SampleTwo} from './SampleTwo/SampleTwo';
This works, however, I get this warning:
Can't make class (SampleOne & SampleTwo) hot reloadable due to being read-only.
To fix this you can try two solutions. First, you can exclude files or directories
(for example, /node_modules/) using 'exclude' option in loader configuration.
Second, if you are using Babel, you can enable loose mode for `es6.modules` using
the 'loose' option. See: http://babeljs.io/docs/advanced/loose/
and http://babeljs.io/docs/usage/options/

After a lot of head-banging, we replaced
export {default as SampleOne} from './SampleOne/SampleOne';
export {default as SampleTwo} from './SampleTwo/SampleTwo';
with
import {default as SampleOne} from './SampleOne/SampleOne';
import {default as SampleTwo} from './SampleTwo/SampleTwo';
export {SampleOne, SampleTwo};
and that seems to be working for us.

I had the same problem since I'm using a index.js in each modules to export all submodules like this:
export {default as SampleOne} from './SampleOne/SampleOne';
export {default as SampleTwo} from './SampleTwo/SampleTwo';
According to the discussion in the react-hot-loader repo, you can either ignore it(since it still got loaded) or don't re-export the modules.

Related

what does babel-plugin-named-asset-import do

Ok I've looked everywhere and there is no documentation on this Babel module
--babel-plugin-named-asset-import
can someone please explain what it is for and how it works.
Looks like its purpose is to import named exports from non JS/CSS assets. Currently, within the CRA, it appears to only be implemented for svg assets. The goal is to offer another way to import SVGs as React components versus the standard import as a url that needs to be applied to an img element.
Without plugin (default import)
import * as React from 'react';
import logo from './logo.png'; // import file as a url
function Header() {
return <img src={logo} alt="logo" />;
}
export default Header;
With plugin (named import)
import * as React from 'react';
import { ReactComponent as Logo } from './logo.svg'; // import file as a React component
function Header() {
return <Logo />;
}
export default Header;
Update
Going deeper, it appears that the plugin aids in importing svg files in the following ways:
import logo from "logo.svg"; // default import
import { logoUrl } from "logo.svg"; // named import
import { ReactComponent as Logo } from "#svgr/webpack?-svgo!logo.svg"; // ReactComponent import
The CRA specifically targets svg file formats as shown in their test suites. As to whether or not it supports other non-js files, not likely (especially since the babel plugin is only utilized once in the CRA webpack config).
As mentioned in the svgr docs:
SVGR can be used as a webpack loader, this way you can import your SVG directly as a React Component.
This particular plugin aims to import any svg file as the default export.
Please note that by default, #svgr/webpack will try to export the React Component via default export if there is no other loader handling svg files with default export.
Whereas the CRA appears to utilize file/url loader for the default/named exports and specifically maps a ReactComponent named export to the svgr webpack plugin.

Importing React Components and Images with require()

In React, what are the differences between loading an image vs. loading a component using require()?
When I load an image using require("image path"), it works. When I load a React component using require("component") I get an error.
For images in React, You need to require
<img src={require('../assests/logo.png')} />
But it is totally different case with components. You import React components bases on how you exported.
And use ES6 to import and export in reactjs
And there are two types of exports
Named Export
Named exports are useful to export several values at ones. During the import, it is important to use the same name.
// how to export
export function myfunc() {}
// how to import
import { myfunc } from './myfile';
Default export.
Default exports are useful to export only a single value. During the import, able to omit the curly bares and use any name.
// how to export
default export function() {}
// how to import
import anynameyouwant from './myfile';

How to import multiple components from one general folder?

I have many components in a components folder. How can I import
them in one line?
For example I have this:
import FormField from "./../components/FormField";
import MultiSelect from "./../components/MultiSelect";
but I want to import it like this:
import {MultiSelect, FormField} from "./../components";
which is not working.
To do like this:
import { MultiSelect, FormField } from "./../components";
In your components folder, create new file: index.js with
export { default as FormField } from './FormField';
export { default as MultiSelect} from './MultiSelect';
Just make index.js in components folder
export * from './FormField';
export * from './MultiSelect';
After this you can easily access.
import {MultiSelect,FormField} from "./../components";
Add index.js in components folder having:
export { default as FormField } from './FormField';
export { default as MultiSelect } from './MultiSelect';
Then in the file where you want to use these components, import them using:
import { MultiSelect,FormField } from "./../components";
There is already an answer for your question. But let me add my 5 cents:
First:
you may import like this: from "../components"; instead of from "./../components";
Second:
I have some experience with imports and I have found out that import {MultiSelect, FormField} from "./../components"; has a lot of pitfalls. You need to create index.js fiels. When you will search MultiSelect uses within your IDE you will always have index.js and that isn't useful. Also if you'll decide to move your file you will have to change 3 files instead of 1 (old index.js new index.js and file that used your MultiSelect).
Is it worth it? It's up too you of course! But now you know what problems you may have :)

importing a new installed module in my react app

I installed a module using npm install into my react project
npm install mdbreact --save
I checked then the nodemodules folder to make sure the lib was installed correctly and yes.
Now I am trying to import some components from the new lib like Input and Button
I am trying
import * as MDB from 'mdbreact';
import Input from 'mdbreact';
and I always get the error error TS2307: Cannot find module 'mdbreact'
Any help how to solve this? Thank you!
It might be helpful to look at how functions and variables are exported, so that you can see how they are imported.
I will explain further, but here are the docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
To export the default variable/function from a file you would use the export default phrase.
var testObj = { 'hello' : 'world' };
export default testObj;
To import the default variable/function from a file you would do it like so:
import testObj from './testFile';
To export a standard variable/function from a file you would use the standard export keyword.
var testObj = { 'hello' : 'world' };
var testObj2 = { 'hello' : 'again' };
export { testObj, testObj2 };
// or if you just want to export testObj - notice the default keyword is missing
export testObj;
To import a standard variable/function from a file you must wrap the imported variable/function inside braces.
TL;DR;
Only the default exported variable/function from a file can be imported without braces, anything else must be imported from within braces. Input is not the default export from mdbreact which is why it must be imported like so:
import { Input } from 'mdbreact';
* will import all available exports from the file, which is why that allowed your import to work. but you don't want to import all components from mdbreact on every file use mdbreact in or your project would become bloated very quickly.

Importing a module in a React Native app

I'm new to the ES6 module system so this may sound silly.
In the React Native Starter App that uses NativeBase, can anyone explain how native-starter-kit/js/components/home/index.js can do
import myTheme from '../../themes/base-theme`;
when the file it is importing from, native-starter-kit/js/themes/base-theme.js did not have any code that export default the variable myTheme?
The 2nd file you are refering to is an entire export default.
On line 5 :
export default {
// Badge
badgeBg: '#ED1727',
badgeColor: '#fff',
...
}
So when they do import myTheme from '../../themes/base-theme; the myTheme is the variable name they chose for the imported module. In this case, the transpiler is going to look for the default export.
If they would have done import { myTheme } from '../../themes/base-theme; then there would have been an issue since it is not explicitly named in the export. Doing this is not refering to the default export but rather the one explicitly called myTheme
I am not sure I made sense, you may want to give https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/import a read
Exporting without default means it's a named export.
You can have multiple named exports in a single file.
Example 1:
export class Theme {}
Here you have to import this export using its exact name.
To use this component in other file you should do this,
import { Theme } from '../../themes/base-theme'
Example 2:
If you export as the default export as,
export default class Theme {}
Then in another file you import the default export without using the { }, like this,
import Theme from '../../themes/base-theme'
There can only be one default export per file.
Although its React's convention to export one component from a file, and to export it is as the default export.
You're free to rename the default export as you import it.
import myTheme from '../../themes/base-theme'

Resources