https://pixabay.com/en/two-way-traffic-two-way-road-148887/
Code (and most anything) is easier to manage when it is in small, bite-size chunks. This is the thinking behind keeping functions to only one task or having files contain only a few, or one, component at a time. If you have a complex app and have to scroll through hundreds or thousands of lines of code, then the job of debugging or just understanding the app becomes that much harder.
Luckily Javascript helps us out with this by having ?imports? and ?exports?. This is how you can write code in one file and share that code so it can be used by another file or files.
The examples I?m going to walk through in this post will be using Node.js and React.js. The React files were created using create-react-app. I?ll start out going through an ES5 example in Node that uses ?require? statements and then show the same thing using ES6 ?import? statements.
ES5 Example
Using ES5 syntax in Node means that the sharing of code between files is done with the ?require? and ?module.exports? statements. A ?module? in Javascript can be thought of as a container that holds related code which can then be exported to another file.
Here are the first three lines for a React app that will, at first, display three colored blocks on the page.
//App.jsvar React = require(‘react’);var Component = React.Component;require(‘./App.css’);var Color = require(‘./Shapes’);
This is setting up a few variables and requiring a few files and libraries. The first is React which is set equal to the ?react? library using the ?require? statement. The second is Component which is set equal to the Component module of the React library. The third line is just using ?require? to include the .css file which doesn?t need to be set to a variable. And finally, the Color variable is set to the value of what is being exported from the ?Shapes.js? file which we will see in a moment.
The rest of this file looks like this.
//App.jsclass App extends Component { render() { return ( <div className=”App”> <div className=”colors”> <Color name=”red”/> <Color name=”green”/> <Color name=”blue”/> </div> </div> ); }}module.exports = App;
This is defining the App component which invokes three Color components and finally exports that component with module.exports.
The Color component looks very similar.
//Shapes.jsvar React = require(‘react’);var Component = React.Component;class Color extends Component { render() { const divStyle = { backgroundColor: this.props.name, color: ‘white’, fontSize: ’20px’, height: ‘100px’, width: ‘100px’ } return ( <div style={divStyle}>{this.props.name}</div> ) }}module.exports = Color;
Again, requiring the necessary React libraries, defining a component, and exporting it. The only addition is the ?divStyle? object which holds CSS values.
The results look like this.
Pretty simple, right?
Exporting multiple components
You can export more than one thing from a file. What if I wanted another component on this page? I could create a new file and require that in ?App.js? or I could just add it to the existing file and export both of them.
This is really going to depend on your preference and your app. Ideally, components are supposed to be reusable in different apps so you should compose them so they stand on their own. However, if your app has two components that will always go together then it may make more sense to have them in one file and export them together.
If I add another component called Animal to the ?Shapes.js? file it will now look like this.
//Shapes.jsvar React = require(‘react’);var Component = React.Component;class Color extends Component { render() { const divStyle = { backgroundColor: this.props.name, color: ‘white’, fontSize: ’20px’, height: ‘100px’, width: ‘100px’ } return ( <div style={divStyle}>{this.props.name}</div> ) }}class Animal extends Component { render() { const divStyle = { fontSize: ’20px’, height: ‘100px’, width: ‘100px’, border: ‘1px solid black’, borderRadius: ‘50%’ } return ( <div style={divStyle}>{this.props.name}</div> ) }}module.exports = Color;
But now there is a problem. I?m only exporting Color. How do I export both of them?
First, I add both components to module.exports.
//Shapes.jsmodule.exports = { Color: Color, Animal: Animal}
So now this file is exporting a module object with two components in it. Because the export is now a bit different, the import has to change a bit too.
//App.jsvar {Color} = require(‘./Shapes’);var {Animal} = require(‘./Shapes’);
Here we are assigning variables to each component but we are enclosing the name of the variable in ?{ }?. You can call these whatever you like, but the name of the variable needs to match the key of the exports object from ?Shapes.js?. And you must use that variable name when invoking the React component
So really this would work too. It wouldn?t be very clear, but it will work.
//Shapes.jsmodule.exports = { Foo: Color, Bar: Animal}//App.jsvar {Foo} = require(‘./Shapes’);var {Bar} = require(‘./Shapes’);class App extends Component { render() { return ( <div className=”App”> <div className=”colors”> <Foo name=”red”/> <Foo name=”green”/> <Foo name=”blue”/> </div> <div className=”animals”> <Bar name=”dog” /> <Bar name=”cat” /> <Bar name=”bird” /> </div> </div> ); }}
The result looks like this.
I did add a ?display: flex? property to App.css to make this layout.
ES6 example
If you are using the ES6 then the idea of imports and exports is the same but the syntax is a bit different
Instead of ?require? you now use ?import? and you can also have an ?export default? statement if you only have one thing to export out of a file.
//App.jsimport React, {Component} from ‘react’;import ‘./App.css’;import {Color, Animal} from ‘./Shapes’;…export default App;//Shapes.jsimport React, {Component} from ‘react’;export class Color extends Component {…export class Animal extends Component {…
In ?Shapes.js? I am exporting each class individually. If I didn?t need to export both of them or only had one, I could also use a export default statement there.
That?s all there is to the basics of importing and exporting between files. The biggest thing to remember about all of these is that you can?t mix them. If you use ?require? statements then you need to use ?module.exports?. Or if you use ?import?, then you can use ?export? or ?export default?. I hope you found this helpful. Please leave a comment or question below. Thanks!