Nodejs开发cli工具
一,用到的模块和包
import chalk from "chalk" // 终端输出颜色
import ora from 'ora' // 终端动画
const program = require('commander') // 命令行接口
const { prompt } = require('inquirer') // 交互式命令行用户界面
const download = require('download-git-repo') // 下载git仓库
const fs = require('fs') // nodejs文件系统
二,核心代码
// 这两行代码让 import 和 require 在一个文件中混用(需要package.json中加一句 type: moudle)
import { createRequire } from "module";
const require = createRequire(import.meta.url);
import chalk from "chalk"
import ora from 'ora'
const program = require('commander')
const { prompt } = require('inquirer')
const download = require('download-git-repo')
const fs = require('fs')
const version = require("./package.json").version
// 项目模板地址
const templates = {
'uni-app-template': {
url: 'direct:https://gitee.com/cuijl123/uni-vue-vite-ts.git',
script: 'npm run dev:h5'
},
// 'vue-admin-template': {
// url: '',
// script: ''
// }
}
program
.usage("cjl <command>")
.version(version,"-v, --version", "查看当前cli版本")
.option("-h, --help", "查看更多帮助命令");
program
.command('init')
.description('初始化一个项目')
.alias('i')
.action(() =>{
// console.log('init');
prompt([
{
type: 'list',
name: 'template',
message: `What template do you need?`,
choices: Object.keys(templates),
default: 'uni-app-template',
},
// 项目名称
{
type: 'input',
name: 'name',
message: `project name:`,
default: 'myProject',
validate: () => true,
transformer : (val) => val
},
// 项目描述
{
type: 'input',
name: 'description',
message: `project description:`,
default: 'my first project',
validate: () => true,
transformer : (val) => val
},
// 作者
{
type: 'input',
name: 'author',
message: `project author:`,
default: 'cjl',
validate: () => true,
transformer : (val) => val
}
])
.then(async (answers) => {
const projectName = answers.name
const url = templates[answers.template].url
// 克隆模板仓库到本地
await clone(url, projectName)
// 修改下载到本地的项目的package.json文件信息
resetPackage(answers)
})
})
program.parse(process.argv)
function clone(url, projectName) {
return new Promise((resolve, reject) => {
const snipper = ora(chalk.green('loading......'))
snipper.start()
download(url, projectName, { clone: true }, (err) => {
if(err){
console.log(chalk.red(err))
return snipper.fail()
}
snipper.succeed()
resolve()
})
})
}
function resetPackage(answers) {
const projectName = answers.name
const command = templates[answers.template].script
const { description, author } = answers
const snipper = ora(chalk.green('初始化项目...'))
snipper.start()
fs.readFile(`./${projectName}/package.json`, 'utf-8', (err, data) => {
if(err) {
snipper.fail()
return console.log(chalk.red(err))
}
const fileData = JSON.parse(data)
fileData.name = projectName
fileData.description = description
fileData.author = author
fs.writeFile(`./${projectName}/package.json`, JSON.stringify(fileData, null, 2), (err, data) => {
if(err) {
snipper.fail()
return console.log(chalk.red(err))
}
snipper.succeed()
console.log(chalk.green('项目已初始化完成,您可以执行以下命令:'))
console.log(`${chalk.yellow(`cd ${projectName}`)}`)
console.log(`${chalk.yellow(`npm install`)}`)
console.log(`${chalk.yellow(`${command}`)}`)
})
})
}
二,本地测试
使用npm link
1, package.json中添加

2,index.js文件开头

3,在该项目下执行npm link
4,输入cjl运行, 可以看到下面的帮助信息

5, cjl init 成功

三,发布到npm
1, npm官网注册账号
2, 命令行中登录 npm login
3, 使用npm源 (因为淘宝镜像源是只读源,所以要发布npm需要去npm源,不修改会报错)
// 设置为官方源: npm config set registry https://registry.npmjs.org/ // 设置为淘宝源: npm config set registry https://registry.npm.taobao.org/
4, 进入需要发布的目录 npm publish
5, 如果要更新版本,需要修改package.json里面的"version": "1.1.0",否则无法再次提交

浙公网安备 33010602011771号