React Native importing function from another file - javascript

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

Related

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

import { Component, Vue } from "vue-property-decorator" vs. import Vue from "vue"

What's the difference and use cases between importing Vue from vue-property-decorator and vue? What I understood I need to import Vue from vue-property-decorator always when defining a custom component with a #Component decorator, but are there any unexpected/different things/scenarios related to the Vue's core which I should be aware when doing so?
I would say that there is no difference according to sources of vue-property-decorator.
vue-property-decorator just does the following:
import Vue, { PropOptions, WatchOptions } from 'vue'
// ...
export { Component, Vue, mixins as Mixins }
Possible that it is done to reduce number of imports in your code:
import {Vue, Smth1, Smth2}` from 'vue-property-decorator';
vs
import Vue from 'vue';
import {Smth1, Smth2} from 'vue-property-decorator';
Let's say you have a very simple module named 'some-module', in it you have:
var foo = 'bar';
export default foo;
export function helloWorld () { ... };
When you do:
import something from 'some-module';
you are only importing the default export of 'some-module'. In this case, it is the string foo. The default export can be anything, object, function, etc.
When you do:
import {helloWorld} from 'some-module';
You are specifically importing a member of 'some-module' named 'helloWorld' and not the default export. In this case, it is the function 'helloWorld'.
If you had done:
import {something} from 'some-module';
The 'something' would be 'undefined' since there is no export for with that name.
You can read more here

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

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!

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

Categories