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"
,否则无法再次提交