{{ messages[0].message }}

Writing node scripts to make your life easier

Often times I find myself performing some tasks over and over. These tasks range from small tasks such as creating similar files in my project to large tasks such as backing up all my production databases. Having scripts that automate these tasks can greatly improve your workflow and productivity.

In this article, I'll show you how I wrote a node js script to generate React presentation and container components automatically in my projects.

Lately, I've been working on a large reactjs project, and in this project, all the container components have this format:


import { connect } from 'react-redux'
import React, { Component } from 'react'

// components
import MyComponent from '@/components/MyComponent'

class MyComponentContainer extends Component {
    render() {
        return <MyComponent />
    }
}
export default connect()(MyComponentContainer)

The presentational components are a little more basic:


import React from 'react'

const MyComponent = () => <div>MyComponent works !</div>

export default MyComponent

Now, this might not seem like much, but when you create a new set of components like these at least twice every day, it becomes annoying, so I wrote a node js script to automatically generate these files anytime I need.

Creating the project

I started by creating a simple node.js project. In it, I created an index.js file.


const Fs = require('fs')
const Path = require('path')

const componentName = process.argv[2]

The name of the component will be passed as an argument when the command is run. I planned to run the command using node, something like this: node bin/index.js ComponentName. This command has three arguments, and to get the third one, we access it using process.argv[2]. Next thing I needed to do was create the content of the files to be generated:


const Fs = require('fs')
const Path = require('path')

const componentName = process.argv[2]

const containerContent = `import { connect } from 'react-redux'
import React, { Component } from 'react'

// components
import ${componentName} from '@/components/${componentName}'

class ${componentName}Container extends Component {
    render() {
        return <${componentName} />
    }
}
export default connect()(${componentName}Container)
`

const presentationalContent = `import React from 'react'

const ${componentName} = () => <div>${componentName}</div>

export default ${componentName}
`

I dynamically create the content of these files using the component name. For the container component, I named it ${componentName}Container.

Creating files and folders recursively with the filesystem module

Now the next step was to create these files. Each component is created in a separate folder, so I need to create the folders for the container and presentational components before actually creating the files. Creating folders and files can easily be created with the nodejs filesystem module.


// ...


Fs.mkdirSync(`${process.cwd()}/client/js/components/${componentName}`, {
    recursive: true
})

Fs.mkdirSync(`${process.cwd()}/client/js/containers/${componentName}`, {
    recursive: true
})

Fs.writeFileSync(
    Path.resolve(
        `${process.cwd()}/client/js/components/${componentName}/index.js`
    ),
    presentationalContent,
    { flag: 'w' }
)

Fs.writeFileSync(
    Path.resolve(
        `${process.cwd()}/client/js/containers/${componentName}/index.js`
    ),
    containerContent,
    { flag: 'w' }
)

Here are some things to note:

  • The recursive option indicates whether parent folders should be created. If false and parents folders do not exist, the mkdirSync function throws an error.

  • The { flag: 'w' } option opens the file for writing. It's created if the file does not exist, and truncated if the file already exists.

  • I used process.cwd() so that the files are generated relative to where the command was run, which most likely will be the root of the project.

Generating code for routes

In my project, I also needed to import and register new routes all the time, so I also printed the routes and imports for the newly created component:

// ...

console.log(`
import ${componentName} from '@/containers/${componentName}'


<Route exact component={${componentName}} path="/${componentName.toLowerCase()}" />
`)

That way, I can copy these lines logged to the console and simply paste then in my routes file. Saves me about 10 annoying seconds in total.

Making script globally accessible.

To make this file globally accessible, I simply added an alias called react-generate using the following command:

echo 'alias react-generate="node /path/to/project/bin/index.js"' >> ~/.zshrc

This appends an alias to ~/.zshrc, and now in any react project I am working on, I can run react-generate NameOfComponent and all components will automatically be generated. Saves me at least 2 minutes every single time, and reduces the number of times I have to be annoyed in a day.

Conclusion

Now, do you need a CLI generator for your react projects? Probably not, but there are most likely a number of tasks you perform on a regular basis. You could easily automate these processes using node js scripts, and writing these scripts will not only sharpen your developer skills but will greatly improve your productivity and speed of development.

Join the weekly newsletter and never miss out on new tips, tutorials, and more.