Reducing redundancy of es6 modules import statement - javascript

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)

Related

import & export icons.js component in react

I create an icons.js file that there are all icons imported from the "react icons package". so How can export this file so that all other components can use it?
Here is my icons.js file
import {BiStore} from 'react-icons/bi';
import {RiBarChartBoxLine} from 'react-icons/ri';
import {RiCalendarTodoLine} from 'react-icons/ri';
import {RiPaintBrushLine} from 'react-icons/ri';
import {RiDatabase2Line} from 'react-icons/ri';
...
LIST GOES ON
...
I try to use the icons.js file in all other components but I don't know how to import & export this file.

Getting error ''element type is invalid expected a string'' with component import in React Native

There is any difference between import Component from 'react' or
import React, {Component} from 'react'? Im getting this error element type is invalid expected a string if I put this import import React, {Component} from 'react' but If I change to the other it's all ok. Its any problem with doing that? Thank you. Im new at coding.
import Component from 'react'
is the same as
import React from 'react'
that's because you are importing the default export of the React package and you can name it as you wish.
import React, { Component } from 'react'
This "Component" refers to React.Component, you are importing "Component" from 'react' plus the default export.
imagine having a file with multiple export named exports.js
const DefaultExport = () => null
export const OtherExport = () => null
export const AnotherExport = () => null
export default DefaultExport
You can import your component using
import something from './exports' //this is DefaultExport
import { OtherExport } from './exports' //OtherExport
import { AnotherExport as RandomExport } from './exports' //AnotherExport
import * as Exports from './exports' //you are importing all the exports
for the last case import * as Exports from './exports' you can access and use all the exports from the file, such as
Exports.default //refer to default export
Exports.OtherExport //refer to OtherExport
Exports.AnotherExport //refer to AnotherExport
What i do is :
import React, {Component} from 'react';
then you can use it in class like:
class Login extends Component
the usage of {Component} is nothing but you are destructuring the import ,
Like if you would have done :
import React, {Component} from 'react';
thenyou would have used it like :
class Login extends React.Component
Thats the difference, hope it helps.
Feel free for doubts
Component is not exported by default from react, so you need to import it with destructuring

Standard Way for React Import Statements

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

'React' must be in scope when using JSX react/react-in-jsx-scope when trying to do it from a index file?

I am trying to aggregate all imports at one location and then export it for other components to use
I have a src/car folder with car.js and index.js inside it
code inside index.js is as below
import React from 'react';
import ReactDOM from 'react-dom';
export {React, ReactDOM}
code inside car.js is as below
import * as Wfmimport from './index';
export class Car extends Wfmimport.React.Component {
render() {
return <h2>Hi, I am a Car!</h2>;
}
}
my src/index.js has following code
import React from 'react';
import ReactDOM from 'react-dom';
import * as name from './car/car'
import './index.css';
ReactDOM.render(<name.Car />, document.getElementById('root'));
when I run the code, I get error "'React' must be in scope when using JSX react/react-in-jsx-scope when trying to do it from a index file"
can anyone help me what is that wrong which I am doing?
My goal is to reduce import statements and hence I am trying the above way

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'],
}

Categories