patternjavascriptMinor
A node CLI to start new projects
Viewed 0 times
projectsnewnodeclistart
Problem
I was annoyed to manually start new projects each time so I made a Node CLI that automate the process. I'm really not comfortable yet with node, so I wanted some advice. It works but I don't know if I did it the node way or not.
Basically the code under here is my whole application. The file structure is like so:
It's not really complicated. What I do in the app is copy the seed and change the project name in package.json. The seed is a template project, with nothing in it beside a starter-repo. I could have upload it to git but this is more fun.
``
Basically the code under here is my whole application. The file structure is like so:
- app.js
- seedIt's not really complicated. What I do in the app is copy the seed and change the project name in package.json. The seed is a template project, with nothing in it beside a starter-repo. I could have upload it to git but this is more fun.
``
#!/usr/bin/env node
const spawn = require('child_process').spawn;
const fs = require("fs");
const path = require('path');
const through2 = require('through2');
const copydir = require('copy-dir');
const name = process.argv[2] || "unnamed project";
const projPath = path.join(process.cwd(), name);
// path to my seed project
const seed = path.join(__dirname, "seed");
if (!fs.existsSync(name)) {
fs.mkdirSync(name);
} else {
throw new Error(directory ${name} already exist);
}
copydir(seed, path.join(process.cwd(), name), function(err) {
if (err) {
console.log(err);
process.exit(1);
}
const package = path.join(projPath, "package.json");
// in my seed project package.json, I have name: "-your-app-name-here-"
replaceInFile(package, "-your-app-name-here-", name, onCopyDone);
});
function onCopyDone(err) {
if (!err)
install(projPath)
else
console.log(err)
}
function replaceInFile(someFile, rep, by, cb) {
fs.readFile(someFile, 'utf8', function(err, data) {
if (err) {
return console.log(err);
}
let result = data.replace(rep, by);
fs.writeFile(someFile, result, 'utf8', cb);
});
}
function install(where) {
console.log('installing dependencies...')
const i = spawn('npm', ['install', '--prefix', where]);
i.stdout.on('data', (data) => {
console.log(stdout: ${dSolution
Avoiding
If you can avoid
The error can be thrown the error if the name exists, but if not just go ahead with the call to
In some cases you may have to manually
Use
It is wise to get in the habit of using
Arrow functions
The parentheses are not necessary on arrow functions with only one argument. Also, a single line doesn't need to have brackets - while this would lead to the return value of the statement getting returned, it shouldn't matter in most cases - so this:
can be simplified to:
elseIf you can avoid
else then it can simplify indentation. For example: if (!fs.existsSync(name)) {
fs.mkdirSync(name);
} else {
throw new Error(`directory ${name} already exist`);
}The error can be thrown the error if the name exists, but if not just go ahead with the call to
fs.mkdirSync():if (fs.existsSync(name)) {
throw new Error(`directory ${name} already exist`);
}
fs.mkdirSync(name);In some cases you may have to manually
return or exit if the statement inside the first conditional doesn't return early or terminate the process - e.g. inside onCopyDone().Use
const instead of let when appropriateIt is wise to get in the habit of using
const for any value that doesn't get re-assigned. Then if you need to have a variable that changes, switch to using let. This affects variables like result in the callback inside replaceInFile().Arrow functions
The parentheses are not necessary on arrow functions with only one argument. Also, a single line doesn't need to have brackets - while this would lead to the return value of the statement getting returned, it shouldn't matter in most cases - so this:
i.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});can be simplified to:
i.stdout.on('data', data => console.log(`stdout: ${data}`));Code Snippets
if (!fs.existsSync(name)) {
fs.mkdirSync(name);
} else {
throw new Error(`directory ${name} already exist`);
}if (fs.existsSync(name)) {
throw new Error(`directory ${name} already exist`);
}
fs.mkdirSync(name);i.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});i.stdout.on('data', data => console.log(`stdout: ${data}`));Context
StackExchange Code Review Q#157389, answer score: 2
Revisions (0)
No revisions yet.