Scaffold your project components using your own templates.
I'm super lazy, and I hate repetitive work. If it can be automated, it should be. This is the main motivation behind noijs
.
At work you'll find yourself:
- Creating components when working on a react app.
- Implementing new endpoints when working on an API.
- Data functions
- Shell scripts
- Scheduled jobs
If you think of it, usually these pieces of code have a very well defined structure. For example, a react component would look something like:
import {FC} from 'react';
import classNames from 'classnames';
import styles from './MyComponent.module.scss';
interface MyComponentProps {
className: string;
}
const MyComponent: FC<MyComponentProps> = ({ className }) => {
return (
<div className={classNames('MyComponent', className)}>
Content here
</div>
);
}
And it also needs stylesheet and tests files. Creating the directory structure and every file by hand, and writing all this stuff over and over is a waste of time. Even more when starting a project from scratch, because you'll be doing this a lot.
noijs
allows you to automate this process, so that you can focus on writing the business logic.
Wanna try it? Simply run:
npm install -g noijs
That's it. Make sure you've added your $HOME/.npm-global/bin
(or whatever your global npm directory is) to the $PATH variable. Once you do this, you should be able to run:
noi
And you should see No templates found
in the screen. If you see it, then your can move on to the next section.
Let's create a template for a react component. Start by creating a .noi
directory somewhere. You can add it in your project root if these templates are project-specific, or you can add them to ~/.noi
and they'll be available to all projects.
The file structure for a noi template looks something like this:
.noi
|__ react-component
|__ config.js
|__ templates
|__ component.template
The templates
directory should contain one template for each file this noi config will create. In this case, we simply want it to create the MyComponent.tsx
file.
The config.js
file allows you to define wizzard-like prompts for the user to enter information, like the component name and any other value you may need to render your template.
A config file for our react component template would look something like this:
module.exports = {
params: {
properties: {
componentName: {
description: 'Enter a name for the component (e.g. LoginForm)',
required: true
}
}
},
run(data, noi) {
console.log(data.componentName);
}
};
In the above code, we define a noi config file that simply defines one prompt for the user, asking them to enter a name for the component. The information the user inputs in these prompts will be available in the data
parameter of the run()
method.
Appart from the data collected from the prompts, the run function also receives an noi
instance. This instance contains a bunch of utility functions to help you create directories, files, render templates, and other helpful actions. See the Utility Functions section.
Now let's render our templates and create our component file.
module.exports = {
// ...
run(data, noi) {
const componentsDir = `${process.cwd()}/components`;
noi.fileFromTemplate({
template: '${__dirname}/templates/component',
data: data,
dest: `${componentsDir}/${data.componentName}.tsx`
});
}
}
Lastly, let's define our templates. To inject the data into the templates, simply use the {% propName %}
syntax.
// File: templates/component.template
import {FC} from 'react';
import classNames from 'classnames';
import './{% componentName %}.less';
interface {% componentName %}Props {
className: string;
}
const MyComponent: FC<{% componentName %}Props> = ({ className }) => {
return (
<div className={classNames('{% componentName %}', className)}>
Content here
</div>
);
}
.{% componentName %} {
// Styles go in here.
}
That's it, we're done defining our first noi template.
Now if you run noi ls
you should see:
Available templates:
react-component
Now that you have a noi config, let's execute it. Simply cd
into the directory containing the components
folder and run:
noi react-component
You should see something like:
Enter a name for your component (e.g. LoginForm):
Simply enter a name for the component and press Enter
. Now, if you run ls components
you should see the new component file.
Now you have automated the scaffolding of a simple react component. In this example we simply created one file, but in real-life examples you may be creating several files, appending some content to existing files, and so on.
noi.file(filePath, content)
Creates a new file with the given content.
noi.fileFromTemplate({ template, data, dest })
Renders the template at the given template
path using the data
object as context. It then creates a new file in the dest
path with the rendered template.
noi.exists(path)
Returns a boolean indicating whether the file exists or not.
noi.appendToFile(filePath, content)
Appends the given content to the end of the file.
noi.appendTemplateToFile({ template, data, file })
Renders the template
using the given data
and appends it at the end of the given file
path.
noi.exec(cmd)
[Async] Executes the given command. It returns a promise that resolves to the stdout
.
noi.cd(path)
Changes the current working directory to the given path.
noi.mkdir(path)
[Async] Creates a new directory at the given path.
noi.cp(src, dest)
[Async] Copies the src
file to the dest
path.