在一些带有交互的库,如webpack、gulp、create-react-app 、vue-cli 这种带有交互显示的库,或者自己写一个脚手架也可以,通常都会用一些小工具,整理一下
validate-npm-package-name
判断一个包是否是npm的有效包, 注意,只是判断包名字是否合法,不判断是否存在
var validate = require("validate-npm-package-name")
// 如果有效,会返回
// { validForNewPackages: true, validForOldPackages: true }
chalk
命令行字体带颜色
const chalk = require('chalk');
console.log(chalk.blue('Hello world!'));
ora
命令行加载 loading 转圈
const ora = require('ora');
const spinner = ora({
text: `Loading ${chalk.green('unicorns')}`,
color: 'green'
})
spinner.start();
setTimeout(() => {
spinner.color = 'yellow';
spinner.text = 'Load finish';
spinner.stop();
}, 3333);
cross-env
运行script 兼容各平台 设置环境变量
{
"scripts": {
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
}
}
rimraf
rm -rf 的功能
// 同步删除文件夹
const rm = require("rimraf").sync;
rm("dist")
user-home
获取用户主目录
var userHome = require('user-home');
console.log(userHome); // D:\Users\david\
tildify
把正常路径转成 ~/
const tildify = require('tildify');
console.log(tildify(userHome+"/dev/huahua")); // ~\dev\huahua
import-local
让一个全局安装包使用本地版本
const importLocal = require('import-local');
if (importLocal(__filename)) {
console.log('Using local version of this package');
} else {
// Code for both global and local version here…
}
my-local-ip
获取本机IP
console.log(require('my-local-ip')())
//==> 192.168.1.33
semver
版本控制,如,需要一个库或者工具最低版本,然后提示
const semver = require('semver')
// 比如需要nodejs版本11,本地版本是10,那就肯定不行,
// 很多工具cli都用这个
semver.satisfies('v10.12.0', ''v11.12.0“”) // false
slash
转换windows斜杠成规范斜杠
const path = require('path');
const slash = require('slash');
const string = path.join('foo', 'bar');
// Unix => foo/bar
// Windows => foo\\bar
slash(string);
// Unix => foo/bar
// Windows => foo/bar
minimatch
简单的正则匹配库
var minimatch = require("minimatch")
minimatch("bar.foo", "*.foo") // true!
minimatch("bar.foo", "*.bar") // false!
minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
multimatch
minimatch 的多重版
const multimatch = require('multimatch');
multimatch(['unicorn', 'cake', 'rainbows'], ['*', '!cake']);
//=> ['unicorn', 'rainbows']
minimist
解析命令行参数
const minimist = require('minimist')
const argv = minimist(process.argv.slice(2));
console.log(argv);
// node aa.js -a beep -b boop
// 结果 { _: [], a: 'beep', b: 'boop' }
markdown
markdown 转html
var markdown = require( "markdown" ).markdown;
console.log( markdown.toHTML( "Hello *World*!" ) )
needle
简单易用的node http客户端
let needle = require('needle');
// 基本get请求
needle.get('https://blog.csdn.net/qq_29334605/article/details/105411279', function(error, response) {
console.log(response);
});
// 操作流
var out = fs.createWriteStream('logo.png');
needle.get('https://google.com/images/logo.png').pipe(out).on('done', function() {
console.log('Pipe finished!');
});
download-git-repo
下载一个git的项目
const download = require('download-git-repo')
// 如果是github的项目,默认可以写地址,只写用户id和项目名
download("single-spa/single-spa", "C:\\Users\\starbooks\\Desktop\\spa", function (err) {
if(err) console.log(err)
})
cli-prompt
一个简单的提示工具
let prompt = require('cli-prompt');
prompt('enter your first name: ', function (val) {
let first = val;
prompt('and your last name: ', function (val) {
console.log('hi, ' + first + ' ' + val + '!');
process.exit(0)
}, function (err) {
console.error('unable to read last name: ' + err);
});
}, function (err) {
console.error('unable to read first name: ' + err);
});
inquirer
terminal交互工具
const inquirer = require('inquirer');
const promptList = [
{
type: 'input',
message: '设置一个用户名:',
name: 'name',
prefix: "vue-cli", // 前缀 默认是问号
default: "test_user" // 默认值
},
{
type: "password", // 密码为密文输入
message: "请输入密码:",
name: "pwd"
},
{
type: 'input',
message: '请输入手机号:',
name: 'phone',
validate: function (val) {
if (val.match(/\d{11}/g)) { // 校验位数
return true;
}
return "请输入11位数字";
}
},
{
type: "confirm",
message: "是否使用监听?",
name: "watch"
},
{
// 多选
type: "checkbox",
message: "选择颜色:",
name: "color",
choices: [
"red",
"blur",
"green",
"yellow"
],
// pageSize: 2 // 设置行数
},
{
type: 'list',
message: '请选择一种语言:',
name: 'lang',
choices: [
"C++",
"Java",
"Python"
],
filter: function (val) { // 使用filter将回答变为小写
return val.toLowerCase();
}
},
{
// rawlist 和 list 一样,但是选项是数字
type: 'rawlist',
message: '请选择一种水果:',
name: 'fruit',
choices: [
"Apple",
"Pear",
"Banana"
]
},
{
type: "editor",
message: "请输入备注:",
name: "editor"
}
];
inquirer.prompt(promptList).then(answers => {
console.log(answers); // 返回的结果
})
yargs
主要处理命令行参数
// 1. 基本
// let argv = require('yargs').argv;
// hello --name=tom 返回 { name : 'tom'}
// 2. alias
let argv = require('yargs').alias('n','name').argv
// hello -n tom 返回 { name : 'tom', n: 'tom'}
// 3. 返回不是 - 开头的参数
console.log(argv._);
// 4. 默认配置
let argv = require('yargs')
.option('n',{
alias:'name',
default:'huahua',
type:'string'
}).argv
fs-extra
fs extra添加本机fs模块中不包含的文件系统方法,并向fs方法添加promise支持,它可以是fs的替代品。主要分为两大类 Async 和 Sync方法
// 复制文件
fs.copy('/tmp/myfile', '/tmp/mynewfile')
.then(() => console.log('success!'))
.catch(err => console.error(err))
// 删除目录
fse.remove('/Users/davod/Desktop/kk', err => {
if (err) return console.error(err)
console.log('success!')
})
// 确保目录为空。如果目录不为空,则删除目录内容。如果该目录不存在,则创建该目录。目录本身不会被删除
fse.emptyDir('/Users/zhangyuhua583/Desktop/kk', err => {
if (err) return console.error(err)
console.log('success!')
})
// 移动文件
const srcpath = '/tmp/file.txt'
const dstpath = '/tmp/this/path/does/not/exist/file.txt'
fse.move(srcpath, dstpath, err => {
if (err) return console.error(err)
console.log('success!')
})
Handlebars
前端模板引擎
// 默认使用 {{ }} 绑定变量
var template = Handlebars.compile("Handlebars <b>{{doesWhat}}</b>");
// 编译结果
console.log(template({ doesWhat: "rocks!" }));
// helpers 可用于实现不属于Handlebar语言本身的功能
Handlebars.registerHelper('upp', function (aString) {
return aString.toUpperCase()
})
// 这么使用
var template = Handlebars.compile("Handlebars <b>{{upp doesWhat}}</b>");
// 内置 helper 和 v-if 差不多
<div class="entry">
{{#if author}}
<h1>{{firstName}} {{lastName}}</h1>
{{/if}}
</div>
// with 绑定一个对象
{{#with person}}
{{firstname}} {{lastname}}
{{/with}}
consolidate
模板引擎的结合体。包括了常用的jade和ejs。通过配置我们就可以使用多种模板引擎
var cons = require('consolidate');
cons.swig('views/page.html', { user: 'tobi' })
.then(function (html) {
console.log(html);
})
.catch(function (err) {
throw err;
});
metalsmith
metalsmith, 一个非常简单,可以插入的static 站点生成器,运行机制,1 读取原目录所有文件 2 调用一系列插件处理文件 3 输出文件到目标路径
const MetalSmith = require('metalsmith');
// 处理md的插件
const markdown = require("metalsmith-markdown");
// 一个模板文件包裹你的 {{ contents }}
// 默认 .njk 文件用 nunjucks引擎 .hbs 用 handlebars引擎
const layouts = require('metalsmith-layouts');
const {render} = require('consolidate').handlebars;
let async = require('async');
// source("./lib") 修改源码目录 默认 ./src 内容文件可以在头部yaml语法执行layout文件
// destination 修改目标路径 默认 ./build
// MetalSmith 参数必填 工作目录
// clean 生成目标文件时候,是否清除原来的文件,默认true
// metadata(obj) 定义metadata对象 obj
const app = MetalSmith(__dirname).source("./src").destination("./des").clean(true)
/**
* @param files 所有文件的对象
* @param metalsmith 当前metalsmith的实例
* @param done 执行下个的方法
*/
const getUserData = function (files, app, done) {
// 此处可使用一些交互工具获取用户输入的信息 此处就写死了
const data = app.metadata();
data.name = "starbooks";
data.url = "https://blog.csdn.net/qq_29334605";
data.description = "hello world !!";
done()
}
// 替换占位符
const template = (files, app, done) => {
let keys = Object.keys(files);
let metadata = app.metadata();
async.each(keys, run, done);
function run(file, done) {
let str = files[file].contents.toString();
render(str, metadata, function (err, res) {
if (err) return done(err);
files[file].contents = Buffer.from(res);
done();
});
}
}
// use 类似中间件
app.
use(getUserData).
// use(markdown())
// .use(layouts({
// engine: 'handlebars', // 指定渲染引擎
// directory: 'layouts' // layout 目录,默认就是layouts
// pattern: "**/*.html" // 匹配的文件才会被处理
// }))
use(template).
build(function (err, files) {
if (err) throw err;
console.log("success");
});
yaml-front-matter、gray-matter
一个把YAML(是一种递归缩写,是一个可读性高并且容易被人类阅读,容易和脚本语言交互,用来表达资料序列的编程语言) 转化成 json的包 内部使用gray-matter,更轻量一些
---
name: Derek Worthen
age: 127
contact:
email: email@domain.com
address: some location
pets:
- cat
- dog
- bat
match: !!js/regexp /pattern/gim
run: !!js/function function() { }
---
Some Other content
// 上边 --- 和 --- 中间的内容 叫做 frontmatter
// 以上为文件内容
var fs = require('fs');
var yamlFront = require('yaml-front-matter');
fs.readFile('./some/file.txt', 'utf8', function(fileContents) {
console.log(yamlFront.loadFront(fileContents));
});