node命令行工具—cf-cli
音乐分享:
初喜《冠军》 后喜《龙王》
(PS:听一次钢心乐队的演出后采访才知道 “龙王”隐喻的是一起喝酒的老铁。。。。)
——————————————————————————————————————————————————————————————————————
项目截图:
项目地址:https://github.com/uustoboy/create-cli
项目目录:
├── bin
│ └── cf.js
├── lib
│ ├── class.js
│ └── templates
├── node_modules
│
└── package.json
第一步 主要靠Commander 命令行框架 和 inquirer 交互命令
cf.js代码:(主要命令的配置)
#!/usr/bin/env node
'use strict';
const program = require('commander');
const appInfo = require('./../package.json');
const _class = require('../lib/class.js');
const log = console.log;
program
.version(appInfo.version)
.usage('创建简单前端项目! [options] <package>')
.parse(process.argv);
program
.command('delete')
.alias('del')
.description('删除操作')
.action((cmd,option) => {
_class(cmd,option);
})
program
.command('app [cmd]')
.alias('a')
.description('创建app项目文件夹')
.option('-y, --fast', '快速创建默认目录')
.action((cmd,option) => {
_class(cmd,option);
}).on('--help', function() {
// 图片文字 http://ascii.mastervb.net/text_to_ascii.php
log(" ___ __ _ ");
log(" .' ..] [ | (_) ");
log(" .---. _| |_ ______ .---. | | __ ");
log(" / /'`\]'-| |-'|______|/ /'`\] | | [ | ");
log(" | \__. | | | \__. | | | | ");
log(" '.___.' [___] '.___.'[___][___] ");
log();
log(' app 创建app项目文件夹');
log();
log(' -y, --fast 快速创建默认目录');
log();
});
program
.command('pc [cmd]')
.alias('p')
.description('创建pc项目文件夹')
.option('-y, --fast', '快速创建默认目录')
.action((cmd,option) => {
_class(cmd,option);
}).on('--help', function() {
// 图片文字 http://ascii.mastervb.net/text_to_ascii.php
log(" ___ __ _ ");
log(" .' ..] [ | (_) ");
log(" .---. _| |_ ______ .---. | | __ ");
log(" / /'`\]'-| |-'|______|/ /'`\] | | [ | ");
log(" | \__. | | | \__. | | | | ");
log(" '.___.' [___] '.___.'[___][___] ");
log();
log(' pc 创建pc项目文件夹');
log();
log(' -y, --fast 快速创建默认目录');
log();
});
//默认不传参数输出help
if (!process.argv[2]) {
program.help();
}
program.parse(process.argv);
class.js代码:(主要是处理交互命令执行)
'use strict';
const log = console.log;
const program = require('commander');
const Gitdownload = require('download-git-repo');
const download = require('download');
const path = require('path');
const fs = require('fs');
const inquirer = require('inquirer');
const fse = require('fs-extra');
const del = require('del');
const archiver = require('archiver');
const chalk = require('chalk');
const join = path.join;
module.exports = function(cmd,option) {
var promps = [];
let _path = getPath( cmd );
if( option._name == 'delete' ){
if( !isFile( _path ) ){
return log(chalk.yellow(`${cmd}不存在`));
}
promps.push({
type: 'confirm',
name: 'del',
message: '是否删除'+cmd
});
inquirer.prompt(promps).then(function (answers) {
if( answers.del ){
del([ _path ])
.then( (err)=>{
//if(err) return log(chalk.red(err));
log(chalk.green('删除完成!~'));
});
}
});
}else if( option._name == 'app' || option._name == 'pc' ){
if( isFile( _path ) ){
return log(chalk.yellow(`${cmd}已存在`));
}
if( option.fast ){
var answers = {
base : false,
framework : false,
sass:true
}
createInfo( answers,cmd,option);
}else{
createFile(cmd,option);
}
}
};
//判断文件/文件夹是否存在;
var isFile = ( _path ) => fse.pathExistsSync( _path )?true:false;
var getPath = ( _path ) => path.resolve( process.cwd(),_path );
function createInfo( answers,cmd,option ){
fse.ensureDir(cmd)
.then(() => {
let jsStr = '';
log(chalk.green(`${cmd}文件夹创建~`));
fse.ensureDir( join(cmd,'c') ).then(() => {
if( answers.base ){
let baseAs = join(__dirname,'..','lib/templates/',option._name,'base.css');
let baseBs = join(process.cwd(),cmd,'c','base.css');
fse.readFile(baseAs,'utf8').then(data=>{
var data = data;
fs.writeFile(baseBs,data,function(){
log(chalk.green('base文件创建~'));
})
});
// fse.ensureLinkSync( join(__dirname,'..','lib/templates/',option._name,'base.css'), join(process.cwd(),cmd,'c','base.css') );
// log(chalk.green('base文件创建~'));
}
});
fse.ensureDir( join(cmd,'j') ).then(() => {
//加载jquery.js;
if( answers.framework == 'jquery' ){
download('http://apps.bdimg.com/libs/jquery/1.8.3/jquery.min.js', path.join(cmd,'j') ).then(() => {
log(chalk.green('jquery文件创建~'));
});
jsStr = '<script src="j/jquery.min.js"></script>';
}
//加载zepto.js;
if( answers.framework == 'zeop' ){
download('http://apps.bdimg.com/libs/zepto/1.1.4/zepto.min.js', path.join(cmd,'j')).then(() => {
log(chalk.green('zepto文件创建~'));
});
jsStr = '<script src="j/zepto.min.js"></script>';
}
});
fse.ensureDir( join(cmd,'i') );
if( answers.sass ){
fse.ensureDir( join(cmd,'s') ).then(() => {
Gitdownload('uustoboy/base_mixins',join(cmd,'/s/base_mixins'),function(){
var txt = `@charset "UTF-8";\n@import "./base_mixins/_base_mixins.scss";`;
fse.outputFileSync( join( process.cwd(),cmd,'/s/index.scss'), txt);
log(chalk.green('sass文件创建~'));
});
});
}
let as = join(__dirname,'..','lib/templates/',option._name,'index.html');
let bs = join(process.cwd(),cmd,'index.html');
fse.readFile(as,'utf8').then(data=>{
var data = data;
if(answers.base){
var c = data.replace(/<%getCSS%>/g,'<link rel="stylesheet" href="c/base.css">');
}else{
var c = data.replace(/<%getCSS%>/g,'');
}
if( answers.framework ){
var j = c.replace(/<%getJS%>/g,jsStr);
}else{
var j = c.replace(/<%getJS%>/g,jsStr);
}
fs.writeFile(bs,j,function(){
log(chalk.green('默认html文件创建~'));
})
});
});
}
function createFile(cmd,option){
var promps = [];
promps.push({
type: 'confirm',
name: 'base',
message: '创建base.css文件'
});
promps.push({
type: 'list',
name: 'framework',
message: '使用框架库',
choices:[
{
name: '不使用框架库',
value: false
},
{
name: 'jquery.js',
value: 'jquery'
},
{
name: 'zeop.js',
value: 'zeop'
}
]
});
promps.push({
type: 'confirm',
name: 'sass',
message: '是否使用sass'
});
inquirer.prompt(promps).then(function (answers) {
//log(answers)
createInfo(answers,cmd,option);
});
}
第二步 package.json 配置
"bin": { "cf": "bin/cf.js" },
第三步 添加到全局(如果报错很有可能是你的命令名系统本来有了需要你删除在按)
$ sudo npm install . -g
发布模块:
先注册npm账号:(填 用户名、用户密码、邮件)
$ npm adduser
如果注册登录:
$ npm login
发布模块:(第一次发布的时候最好在npm搜搜你package.json里‘name’有木有已经发的要不然发布不了,每一次要发布npm上必须要更改‘version’的版本号)
$ npm publish
(注意:如果npm源更改成淘宝镜像的要改回npm源,淘宝镜像源发布会报错发布不了,推荐使用 nrm 包查看、切换)
删除模板:
$ npm unpublish --force [name]
全局安装模块:
$ npm install [name] -g
参考资料:
极客学院 :《使用 Node.js 开发命令行工具》 (视频教学)