Standard Way for React Import Statements - javascript

I was wondering if there's a standard way to write import statements in react? For example, I have this:
import React, { useState, FormEvent } from 'react';
import Avatar from '#material-ui/core/Avatar';
import {Grid, Checkbox, TextField, FormControlLabel, CssBaseline} from '#material-ui/core';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import { LOGIN } from '../../graphql/mutations/login';
import { schema } from '../../helpers/validations/login';
import { Redirect } from 'react-router-dom';
import { useMutation } from '#apollo/react-hooks';
import StatusMessage from '../../helpers/statusMessages/loginMessage';
import Copyright from '../../components/copyright/copyright';
import CustomButton from '../../components/button/button';
import { ExecutionResult } from 'graphql';
import { Wrapper, StyledLink, Form, StyledTypography, StyledBox, StyledContainer} from './styles';
import { store } from '../../store';
import { useDispatch } from 'react-redux';
import SignInResponse from '../../graphql/responses/login';
import { useFormik } from 'formik';
Are there any rules about whether I should import everything from '#material-ui/core';separately or together? Does it make a difference apart from reducing the number of lines?
Is there any rule about if I should import other local files/functions after react's own libraries/content? Any other rules/suggestions?

There are known standard, most of them are opinions rather than must-dos. I would recommend that you take a look at eslint-plugin-import as it has a extensive list of standards/opinions regarding imports:
Ensure all imports appear before other statements ([first])
Ensure all exports appear after other statements ([exports-last])
Report repeated import of the same module in multiple places ([no-duplicates])
Forbid namespace (a.k.a. "wildcard" *) imports ([no-namespace])
Ensure consistent use of file extension within the import path ([extensions])
Enforce a convention in module import order ([order])
Enforce a newline after import statements ([newline-after-import])
Prefer a default export if module exports a single name ([prefer-default-export])
Limit the maximum number of dependencies a module can have ([max-dependencies])
Forbid unassigned imports ([no-unassigned-import])
Forbid named default exports ([no-named-default])
Forbid default exports ([no-default-export])
Forbid named exports ([no-named-export])
Forbid anonymous values as default exports ([no-anonymous-default-export])
Prefer named exports to be grouped together in a single export declaration ([group-exports])
Enforce a leading comment with the webpackChunkName for dynamic imports ([dynamic-import-chunkname])
Regarding the order, what's recommended is:
node "builtin" modules
"external" modules
"internal" modules
modules from a "parent" directory
"sibling" modules from the same or a sibling's directory
"index" of the current directory

There is no standard way, just personal preferences.
Personally, I prefer to group imports from a common source, like you did in '#material-ui/core';. You could also do that with components, helpers, and similar local modules. Also, I prefer to import first third-party modules and then local modules.
It's all about finding something "logical" and easy to scan to you.

Don't worry about how many lines were used to import modules. I think it's a best practice to first import modules from other vendors, then import local modules. There are some lint rules to enforce that I think.
Other than that, I'd say only import what is needed:
import Avatar from '#material-ui/core/Avatar';
is better than
import * as MaterialUI from '#material-ui/core';

No, there is no standard on how you import something. But instead of import everything just import what you need, it'll also help webpack in tree-shaking unused code. So I would suggest this:
import { Avatar } from '#material-ui/core';
One other I like to do is separate my local imports from the packages imports, it makes the code more readable:
import React, { useState, FormEvent } from 'react';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import { ExecutionResult } from 'graphql';
import { Avatar, Grid, Checkbox, TextField, FormControlLabel, CssBaseline } from '#material-ui/core';
import { Redirect } from 'react-router-dom';
import { useMutation } from '#apollo/react-hooks';
import { useDispatch } from 'react-redux';
import { useFormik } from 'formik';
import { LOGIN } from '../../graphql/mutations/login';
import { schema } from '../../helpers/validations/login';
import { store } from '../../store';
import { Wrapper, StyledLink, Form, StyledTypography, StyledBox, StyledContainer } from './styles';
import StatusMessage from '../../helpers/statusMessages/loginMessage';
import Copyright from '../../components/copyright/copyright';
import CustomButton from '../../components/button/button';
import SignInResponse from '../../graphql/responses/login';

Related

Performance of ES6 imports

In the React Bootstrap docs, it is suggested that modules be imported individually from single distribution files rather than from the larger distribution file.
import Button from 'react-bootstrap/Button';
// or less ideally
import { Button } from 'react-bootstrap';
Why is the second method less ideal?
As that link says:
You should import individual components like: react-bootstrap/Button rather than the entire library. Doing so pulls in only the specific components that you use, which can significantly reduce the amount of code you end up sending to the client.
If you import from react-bootstrap, the client will have to download everything in react-bootstrap. That could end up being quite a large chunk of code. In contrast, if you import from the react-bootstrap/Button, all that needs to be downloaded is the button - nothing extraneous is included.
Compare the file:
https://github.com/react-bootstrap/react-bootstrap/blob/master/src/Button.js
to
https://github.com/react-bootstrap/react-bootstrap/blob/master/src/index.js
As you can see, importing from the Button requires a few imports:
import classNames from 'classnames';
import React from 'react';
import PropTypes from 'prop-types';
import { useBootstrapPrefix } from './ThemeProvider';
import SafeAnchor from './SafeAnchor';
But importing from the index.js requires a very large number of imports, 77, to be precise.
export Accordion from './Accordion';
export AccordionToggle, { useAccordionToggle } from './AccordionToggle';
export AccordionCollapse from './AccordionCollapse';
export Alert from './Alert';
export Badge from './Badge';
// and 72 more
If you import from index instead of from Button, you're downloading a lot of code that you don't need, for no good reason.

How to avoid import everything that the component needs in each test file?

In my jest tests, I need to import everything that the tested component needs to work (which I do in my application's main.js). Since I have multiple test files, I need to "re-import" it in each file. Is there a way to import it all in a single file, and then import only this file?
import Component from '#/views/input-something'
import {mount, shallowMount} from '#vue/test-utils'
import {FontAwesomeIcon} from '#fortawesome/vue-fontawesome'
import {library} from '#fortawesome/fontawesome-svg-core'
import {fas} from '#fortawesome/free-solid-svg-icons'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import 'bootstrap/dist/css/bootstrap.css'
import BootstrapVue from 'bootstrap-vue'
import 'vue-select/dist/vue-select.css'
import Vuelidate from 'vuelidate'
import Vue from 'vue'
import './helpers/multi-ref-test-runner'
Vue.component('font-awesome-icon', FontAwesomeIcon)
Vue.use(BootstrapVue)
Vue.use(Vuelidate)
library.add(fas)
// I wish to write everything above in a single file
window.confirm = function() { return false; }
describe('input-something', () => {
let wrapper;
beforeEach(() => {
wrapper = mount(Component, {...});
});
it('it renders', () => {});
});
I expect to import everything I need in a file, like helper.js
Then in my test file I'd just do something like
import 'test-helpers/helper';
describe('input-something', () => {...})
EDIT 1
After a while I was able to import all I needed this way
/* imports.js */
import Component from '#/components/something'
import { mount } from '#vue/test-utils'
export { Component, mount }
/* my-test.js */
import { Component, mount } from './imports.js'
And adding this line to my .babelrc (to be able to work with jest)
"plugins": ["#babel/plugin-syntax-dynamic-import"]
And then I could use all the properties I imported.
Although it's working this way, I wanted to use these properties (Component, mount...) without having to implicitly import each one.
Is there a way to do it?
create a separate js file
import components or plugins or anything you want there
import that file in main.js file
For example:
this is my separate reuseableComponets.js
// I include components and plugins here
...
import Component from '#/views/input-something'
import {mount, shallowMount} from '#vue/test-utils'
import {FontAwesomeIcon} from '#fortawesome/vue-fontawesome'
...
Now in app.js
import('path to reuseableComponets.js')
That's it.
Use setupFilesAfterEnv in your jest.config.js to point to a script that sets up your tests. This file would be automatically invoked before your tests, so you wouldn't have to import it.
For example, you could move the setup code you had mentioned into a file named my-setup.js, and then configure Jest as follows:
// jest.config.js
module.exports = {
setupFilesAfterEnv: ['./my-setup.js'],
}

What do these different usages of ‘import’ represent?

I'm a newcomer on React, I'm a Little confused about how "import" statements are written. Until now I've seen this 4 styles:
/* This is very clear to me - Here no Problem */
import React from 'react';
/* What does "./" before ListContacts mean? */
import ListContacts from './ListContacts'
/* What "*" and "as" mean on this import statement? */
import * as ContactsAPI from './utils/ContactsAPI'
/*What does { } mean on this import statement? */
import { BrowserRouter } from 'react-router-dom'
Thanks very much for your time
import ListContacts from './ListContacts'
'./' means it's a component that's not in node_modules. Usually ones you've built yourself.
import * as ContactsAPI from './utils/ContactsAPI'
* means you are importing all named exports (so you can use them by name)
import { BrowserRouter } from 'react-router-dom'
{ BrowserRouter }means that you are only importing the component named BrowserRouter from more than one named export.

React Native importing function from another file

I am wondering if I import a function from another file, am I also importing all the files that is imported in the file of the function? For example:
auth.js
import React from 'react';
import { AsyncStorage, View, Text, ScrollView, ... } from 'react-native';
import ModuleA from './modules/ModuleA';
import ModuleB from './modules/ModuleB';
import Module99 from './modules/Module99;
export const function1 = () => {
{/* some function using ModuleA */}
}
export const function2 = (param) => {
if(something)
{/* some function using Module99 */}
else
{/* some function using ModuleB */}
}
Screen.js
import React from 'react';
import { function2 } from '../auth';
export default class Screen extends React.Component {
{/* use function2 in some function or render */
}
My question is, when I import function2 from auth.js, am I importing all the modules and other files that is imported in auth.js? Or am I just importing the module that will be used by function2.
Also, function2 will use different module depending on the param, by calling function2 from my Screen, will my Screen also import all modules, or just Module99 and moduleB, or just the specific module inside the if else statement?
I have read a lot of the documentations on how importing works in react native but still couldn't really understand the flow.
Thank you for all answers.
By doing this import function2 from '../auth'; you are importing nothing as its not default export. Also no modules will automatically be imported in screen.js.
You will have to import explicitly the modules(ModuleA, ModuleB ets) if you also need to use in screen.js
If you want to use function2 in screen.js the you need to import it like this
import { function2 } from '../auth';
You can also use import * as fromAuth from '../auth'; to import all
Usage: fromAuth.function2()
Import without curly braces {} is used for importing defaults.(which has been exported using default keyword)
There are 4 types of exports:
Named exports (several per module)
Default exports (one per module)
Mixed named & default exports
Cyclical Dependencies
Here are some Import examples from MDN
import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
Find more details here

Reducing redundancy of es6 modules import statement

I've started using es6 for a project, and quickly discovered that using import as such:
import {Account} from 'controllers/account'
import {Activity} from 'controllers/activity'
import {BillingEdit} from 'controllers/billing-edit'
import {BillingSummary} from 'controllers/billing-summary'
import {Billing} from 'controllers/billing'
import {BillingPlan} from 'controllers/billing-plan'
import {Components} from 'controllers/components'
import {Dashboard} from 'controllers/dashboard'
import {Devices} from 'controllers/devices'
import {Feedback} from 'controllers/feedback'
import {Frame} from 'controllers/frame'
import {Help} from 'controllers/help'
import {Login} from 'controllers/login'
import {Membership} from 'controllers/membership'
import {Navigation} from 'controllers/navigation'
import {Notifications} from 'controllers/notifications'
import {Password} from 'controllers/password'
import {Perks} from 'controllers/perks'
import {PlanIssues} from 'controllers/plan-issues'
import {PlanClaims} from 'controllers/plan.claims'
import {PlanContract} from 'controllers/plan.contract'
import {PlanDetails} from 'controllers/plan.details'
import {PlanDevices} from 'controllers/plan.devices'
import {Plan} from 'controllers/plan'
import {PlanTerms} from 'controllers/plan.terms'
import {PlanItems} from 'controllers/plan.items'
import {Plans} from 'controllers/plans'
import {Profile} from 'controllers/profile'
Is leading to redundancy, and will become difficult to maintain.
I can of course generate this dynamically by making a task that recurses through the directory, but I'm wondering if es6 has a solution to this problem
If you're happy including all controllers, then you could add a index.js in your controllers folder. In it you would do what you did here and include everything, then you would re-export it all as members of one object.
controllers/index.js
import {Account} from './account'
import {Activity} from './activity'
import {BillingEdit} from './billing-edit'
import {BillingSummary} from './billing-summary'
const controllers = {
Account,
Activity,
BillingEdit,
BillingSummary
}
export default controllers
app.js
import Controllers from './controllers'
// now you can access controllers like this
console.log(Controllers.Account)
console.log(Controllers.BillingSummary)
or you could import only the ones you need like so
app_alt.js
import { Account, Activity } from './controllers'
console.log(Account)
console.log(Activity)
or you can mix and match the approaches
app_mix.js
import Controllers, { Account, Activity } from './controllers'
console.log(Controllers.Account)
console.log(Account)
console.log(Controllers.BillingSummary)

Categories