Building a Command-line Interface in JavaScript with OClif
阿新 • • 發佈:2018-12-31
$ npm init #will create a new package.json file with the data you provide for the current directory
$ npm install oclif #will install the oclif package into your current directory
$ npm remove config #will remove the config package from your current directory
$ npm publish
$ buttercms generate:blog --for=express
$ npm install -g oclif
$ oclif multi your-command
$ ./bin/run hello
$ ./bin/run hello hello world from ./src/commands/hello.ts! $ ./bin/run help USAGE $ mynewcli [COMMAND] COMMANDS hello describe the command here help display help for mynewcli $ ./bin/run help hello describe the command here USAGE $ mynewcli hello [FILE] OPTIONS -f, --force -n, --name=name name to print EXAMPLES $ mynewcli hello hello world from ./src/hello.ts!
$ oclif multi buttercms
'use strict' const {Command, flags} = require('@oclif/command') const requiredir = require("require-dir") const BlogGenerators = requiredir("../../generators/blog") class BlogCommand extends Command { async run() { const {flags} = this.parse(BlogCommand) const targetGeneration = flags.for.toLowerCase().trim() //error handling if(BlogCommand.flags.for.options.indexOf(targetGeneration) == -1) { return this.error (`Target not found '${targetGeneration}', please try one of the valid ones - ${BlogCommand.flags.for.options.join(",")} - `) } const gen = new BlogGenerators[targetGeneration]() gen.run(); } } //Adding for auto-documentation purposes thanks to OClif BlogCommand.flags = { for: flags.string({ description: 'Target destination for the generator command', options: ['express'] //valid options }) } module.exports = BlogCommand
$ ./bin/run generate:blog --for=express
const {flags} = this.parse(BlogCommand)
const targetGeneration = flags.for.toLowerCase().trim()
'use strict'
const {Command} = require('@oclif/command')
const inquirer = require("inquirer")
const chalk = require("chalk")
const fs = require("fs")
const ncp = require("ncp").ncp
const SOURCEEXPRESSBLOG = __dirname + "/express-template"
module.exports = class ExpressBlogGenerator extends Command{
prompts() {
this.log(`The following list of files will be created:
${chalk.green(
['app',
'- /public/javascripts/',
'- /public/images/',
'- /public/stylesheets/',
'- /public/stylesheets/style.css',
' ',
'- /routes/index.js',
'- /routes/authors.js',
'- /routes/categories.js',
'- /routes/blog.js',
' ',
'- /views/error.jade',
'- /views/index.jade',
'- /views/layout.jade',
'- /views/authors.jade',
'- /views/categories.jade',
'- /views/feeds.jade',
'- /views/posts.jade',
'- /views/post.jade',
' ',
'- /app.js',
'- /package.json',
'- /bin/www'
].join("\n")
)}
Also the following routes will be availabe for you:
${chalk.green("- GET")} /categories/:slug
${chalk.green("- GET")} /authors/:slug
${chalk.green("- GET")} /blog/rss
${chalk.green("- GET")} /blog/atom
${chalk.green("- GET")} /blog/pages/:page
${chalk.green("- GET")} /blog
${chalk.green("- GET")} /blog/:slug
`)
return inquirer.prompt([{
type: "confirm",
name: "continue",
message: "Are you sure you wish to continue?",
choices: "Y/n",
default: "Y"
},{
when: response => response.continue,
type: "string",
name: "appname",
message: "What's the name of your blog?"
}])
.then( answer => answer)
.catch( err => false)
}
cleanAppName(appname) {
return appname.trim().toLowerCase().replace(/[^a-zA-Z0-9]/g,"")
}
printSuccessMessage(folderName) {
this.log(chalk.green(`
== CONGRATS ==
Your blog is ready for you to start pumping code into it!
Now you can:
1- cd ./${folderName}
2- npm install
3- npm start
`))
}
/*
Create the destination folder using the application name given,
and copy the blog files into it
*/
copyFiles(appname) {
const folderName = this.cleanAppName(appname)
fs.mkdir(folderName, (err) => {
if(err) {
return this.log("There was a problem creating your blog's folder: " + chalk.red(err.toString()))
}
this.log("Folder - " + chalk.bold(folderName) + " - " + chalk.green("successfully created!"))
ncp(SOURCEEXPRESSBLOG, folderName, (err) => {
if(err) {
return this.log("There was a problem while copying your files: " + chalk.red(err))
}
this.printSuccessMessage(folderName)
})
})
}
execute(answer) {
if(!answer.continue){
return this.log("OK then, see you later!")
}
this.copyFiles(answer.appname)
}
async run() {
this
.prompts() //ask the questions
.then(this.execute.bind(this)) //execute the command
}
}
$ npm link
$ npm start
Found this guide helpful? Get more delivered straight to your inbox.