通过命令行工具,初始化团队项目,并生成团队规范代码,一键创建项目,一键生成代码,一键生成功能模块··· 解放双手,从 cli 开始, JSer 永不为奴!
创建项目目录 两种方法:
鼠标右键创建文件夹,文件夹名称即为项目名称;
打开系统命令面板(powershell、cmd···),输入命令:
初始化 node 项目 在项目文件目录运行命令:
运行命令后会出现如下提示(按照提示完成即可):
根据提示完成操作后,会在项目根目录生成项目描述文件package.json
,可以回车跳过以下步骤,后续在package.json
文件中完善项目信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help init` for definitive documentation on these fields and exactly what they do . Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: 项目名称 version: 版本号 description: 项目描述 entry point: (index.js)入口 test command : 测试相关git repository: git仓库地址 keywords: 关键词 author: 作者 license: 证书 About to write to E:\***\package.json: { "name" : "***" , "version" : "***" , "description" : "***" , "main" : "index.js" , "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" }, "author" : "***" , "license" : "ISC" } Is this OK? (yes) yes
安装相关依赖 项目后续会使用以下依赖包。
运行命令:
1 npm i commander download-git-repo ora handlebars figlet clear chalk open
依赖包介绍:
创建 cli 入口文件 项目根目录创建文件夹bin
,在bin
文件夹中创建mycli.js(自定义)
文件。
文件内容如下:
定义执行命令 打开package.json
文件,添加相关代码(句首有+
号的代码为新增代码):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 { "name" : "***" , "version" : "***" , "description" : "***" , "main" : "index.js" , "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" }, + "bin": { + "mycli": "./bin/mycli.js" + }, "author": "***", "license": "ISC", "dependencies": { "chalk": "^4.1.0", "clear": "^0.1.0", "commander": "^6.2.0", "download-git-repo": "^3.0.2", "figlet": "^1.5.0", "handlebars": "^4.7.6", "open": "^7.3.0", "ora": "^5.1.0" } }
映射命令至系统 将package.json
文件中刚添加的bin
命令映射至系统中。
运行命令:
此时我们可以全局使用bin
中的mycli
命令了。
npm link
机理: 由于已经安装好 node 环境,故此我们可以直接全局使用node
与npm
命令,而npm link
则是将package.json
中bin
下的命令通过npm
与系统环境变量
桥接,所以我们可以全局使用bin
中的命令。
至此我们实现了 cli 的第一步:可以全局使用我们自定义的命令了~~
莫要问我为什么在这里用了彩色的字。。。
因为我比较————
骚!
定制命令行界面 在入口文件bin => mycli.js
中进行命令行界面定制。
1 2 3 4 5 6 7 8 9 10 11 12 13 #!/usr/bin/env node const program = require ('commander' ) program.version(require ('../package.json' ).version) program .command('init <name>' ) .description('init project' ) .action(name => { console .log('init--------' +name); }) program.parse(process.argv)
定制初始化功能 在根目录中创建lib
文件夹,在lib
文件夹中创建init.js
文件,用于编写初始化功能代码。
基础结构搭建 初始化功能基础代码结构。
lib => init.js
文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 const { promisify } = require ('util' ) const figlet = promisify(require ('figlet' )) const clear = require ('clear' ) const chalk = require ('chalk' ); const colorLog = (content, color ) => console .log(chalk[color||'green' ](content));module .exports = async name => { clear(); const data = await figlet('Gisuni Welcome' ); colorLog(data,'red' ) }
连接功能与命令 bin => mycli.js
对init
方法进行引入并使用,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env node const program = require ('commander' ) program.version(require ('../package.json' ).version) program .command('init <name>' ) .description('init project' ) - .action(name => { - console .log('init--------' +name); - }) + .action(require ('../lib/init' )) program.parse(process.argv)
下拉仓库功能 将仓库中的代码下拉至本地。
在lib
文件夹中创建download.js
文件,其代码如下:
1 2 3 4 5 6 7 8 9 10 11 const { promisify } = require ('util' ) module .exports.clone = async (repo, desc) => { const download = promisify(require ('download-git-repo' )) const ora = require ('ora' ) const process = ora(`下载中··· ${repo} ` ) process.start() await download(repo, desc) process.succeed() }
引入下拉功能 将下拉功能引入至初始化模块中。
lib => init.js
文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const { promisify } = require ('util' ) const figlet = promisify(require ('figlet' )) const clear = require ('clear' ) const chalk = require ('chalk' ) const colorLog = (content, color ) => console .log(chalk[color||'green' ](content)) +const { clone } = require ('./download' ) module .exports = async name => { clear(); const data = await figlet('Gisuni Welcome' ); colorLog(data,'red' ); + colorLog(`创建项目:${name} ` ); + await clone('github:用户名/项目名称' , name); }
自动安装依赖 下拉的项目将自动安装依赖包。
lib => init.js
文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 const { promisify } = require ('util' ) const figlet = promisify(require ('figlet' )) const clear = require ('clear' ) const chalk = require ('chalk' ) const colorLog = (content, color ) => console .log(chalk[color||'green' ](content)) const { clone } = require ('./download' ) +const spawn = async (...args) => { + const { spawn } = require ('child_process' ) + return new Promise (resolve => { + const proc = spawn(...args); + proc.stdout.pipe(process.stdout); + proc.stderr.pipe(process.stderr); + proc.on('close' , () => { + resolve(); + }) + }) +} module .exports = async name => { clear(); const data = await figlet('Gisuni Welcome' ); colorLog(data,'red' ); colorLog(`创建项目:${name} ` ); await clone('github:用户名/项目名称' , name); + colorLog('安装依赖中···' ); + await spawn(process.platform === 'win32' ?'npm.cmd' :'npm' , ['install' ], { cwd :`./${name} ` }); + colorLog(` +安装完成! + +项目将自动启动,若未启动请执行如下命令: +============================== + cd ${name} + npm run serve +============================== + ` );+}
项目自启动 依赖安装完成后将自动打开浏览器,并在指定端口(默认 8080 端口)运行服务。
lib => init.js
文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 const { promisify } = require ('util' ) const figlet = promisify(require ('figlet' )) const clear = require ('clear' ) const chalk = require ('chalk' ) const colorLog = (content, color ) => console .log(chalk[color||'green' ](content)) const { clone } = require ('./download' ) +const open = require ('open' ) const spawn = async (...args) => { const { spawn } = require ('child_process' ) return new Promise (resolve => { const proc = spawn(...args); proc.stdout.pipe(process.stdout); proc.stderr.pipe(process.stderr); proc.on('close' , () => { resolve(); }) }) } module .exports = async name => { clear(); const data = await figlet('Gisuni Welcome' ); colorLog(data,'red' ); colorLog(`创建项目:${name} ` ); await clone('github:用户名/项目名称' , name); colorLog('安装依赖中···' ); await spawn(process.platform === 'win32' ?'npm.cmd' :'npm' , ['install' ], { cwd :`./${name} ` }); colorLog(` 安装完成! 项目将自动启动,若未启动请执行如下命令: ============================== cd ${name} npm run serve ============================== ` );+ open('http://localhost:8080' ); + await spawn(process.platform === 'win32' ?'npm.cmd' :'npm' , ['run' ,'serve' ], { cwd :`./${name} ` }); }
其实到这里,一个最基本的 cli 已经制作完成了~~~
那么接下来将开始丰富它的功能!
更新中···
原文作者: ShanYi Hui
原文链接: http://huishanyi.club/2020/11/09/NodeJS/手写cli/
版权声明: 转载请注明出处(必须保留作者署名及链接)