今天咱们来从零构建一个简易的node脚本插件,方便操做shell,构建本身的脚本工具,帮助你们理解一些node模块,webpack打包过程及npm发布过程。javascript
要使用node操做shell,首先要了解node中的child_process.exec,简单的来说,exec会开启一个shell,而且执行输入的命令,就像是你们使用git bash来执行某些命令,如npm init。介绍完了,show code。前端
首先建立一个结构以下的文件夹,并执行npm init -yjava
├─src
│ └─index.js
└─package.json
复制代码
在index.js文件中,编写主要代码。node
首先引入所须要的execwebpack
const util = require('util');
const exec = util.promisify(require('child_process').exec);
复制代码
通常所须要的即三个参数,执行的命令行(command),执行的目录(cwd),执行的超时时间(timeout),即git
exec(command, { cwd: path || null, timeout: timeout || 0 })
复制代码
执行命令的代码以下所示:github
/** * @name: 执行命令行 * @param {Array} cmd/执行命令语句 * @param {String} path/执行命令的路径 * @param {Number} timeout/执行命令的超时时间 * @return: {Boolean} 是否成功 */
const shell = async (arr) => {
for (let i = 0; i < arr.length; i++) {
const { cmd, path, timeout } = arr[i]
// 组装执行命令
const command = cmd.reduce((total, item, index) => {
if (index === 0) {
return total + item
} else {
return total + ` && ${item}`
}
}, '')
const { error, stdout, stderr } = await exec(command, { cwd: path || null, timeout: timeout || 0 });
if (error) {
// 打印错误日志
log(error)
return false
}
}
console.log("完成")
return true
}
复制代码
传入的参数为对象数组arr,对象中的cmd为字符串数组,存放执行的命令行,使用" && "链接每一个命令行,path为执行命令的路径,timeout为该次进程的超时时间,且将执行步骤改成同步。web
执行过程当中可能会出现报错,那么这个时候就须要一个日志来记录错误。shell
引入所需功能npm
const fs = require('fs');
const path = require('path');
复制代码
获取当前时间以备用
/** * @name: 当前时间 * @param {String} type/date为日期,time精确到秒 * @return: {String} 当前时间 */
const timeStr = (type) => {
const zeroFill = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
const date = new Date()
const year = date.getFullYear()
const month = zeroFill(date.getMonth() + 1)
const day = zeroFill(date.getDate())
const hour = zeroFill(date.getHours())
const minute = zeroFill(date.getMinutes())
const second = zeroFill(date.getSeconds())
if (type === "date") {
return `${year}-${month}-${day}`
}
if (type === "time") {
return `${year}-${month}-${day} ${hour}:${minute}:${second}`
}
}
// 当前日期
const date = timeStr("date")
// 当前时间
const time = timeStr("time")
复制代码
输出错误日志
/** * @name: 输出错误日志 * @param {type} error/错误信息 * @return: */
const log = error => {
const logPath = path.join(__dirname, "log")
const txtPath = path.join(__dirname, "log", `${date}.txt`)
if (!fs.existsSync(logPath)) {
// 不存在log目录,则建立
fs.mkdirSync(logPath)
}
if (!fs.existsSync(txtPath)) {
// 不存在错误日志文件,则建立
fs.writeFileSync(txtPath, `${time} ${error}; \n`)
} else {
// 存在则追加错误信息
fs.appendFileSync(txtPath, `${time} ${error}; \n`)
}
}
复制代码
使用fs.existsSync检查是否存在log目录,若是不存在则使用fs.mkdirSync建立目录。
再检查是否有当天的错误日志文件,不存在则使用fs.writeFileSync建立文件,并写入错误信息与时间; 若存在,则对这个错误日志文件使用fs.appendFileSync追加错误信息。
最后经过
module.exports = shell
复制代码
导出
以后在src目录下建立一个example文件来检测下刚刚的代码是否能够成功运行。
const shell = require("./index")
shell([{ cmd: ["mkdir pikaz-shell"], path: "D:\\" }])
复制代码
此命令会在D盘建立一个pikaz-shell文件夹
执行
node src/example
复制代码
当在D盘看到新建立的文件夹时,就说明代码可成功运行了。
代码编写完,就须要打包了,咱们使用webpack来打包。
安装webpack
npm install webpack webpack-cli --save-dev
复制代码
在项目目录下建立webpack.config.js配置文件,内容以下:
const path = require('path');
module.exports = {
mode: 'production',
entry: {
"pikaz-shell": "./src/index.js",
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'lib'),
libraryTarget: 'umd'
},
node: {
fs: 'empty',
child_process: 'empty',
}
};
复制代码
其中,mode为打包模式,设置为production生产模式,可自动压缩代码。
entry为打包的入口,设置为src目录下的index文件。
output为输出文件,咱们设置到lib文件夹下,libraryTarget通常都设置为umd,便可将你的 library 暴露为全部的模块定义下均可运行的方式。它将在 CommonJS, AMD 环境下运行,或将模块导出到 global 下的变量。
node将fs和child_process设置为'empty',由于咱们使用的node是计算机安装的全局node,这样设置webpack就不会查找这两个模块,否则会报错在该项目查找不到这两个模块。
最后将打包命令"build": "webpack"添加进package.json的scripts中
发布首先须要一个npm帐号,能够本身去https://www.npmjs.com/注册一个。
有帐号则继续接下来的操做。 对package.json文件设置以下:
{
"name": "pikaz-shell",
"version": "0.1.4",
"description": "javascript for manipulating the shell",
"main": "lib/pikaz-shell.js",
"scripts": {
"build": "webpack",
"example": "node src/example"
},
"keywords": [
"node",
"shell"
],
"files": [
"lib"
],
"repository": {
"type": "git",
"url": "https://github.com/pikaz-18/pikaz-shell.git"
},
"bugs": {
"url": "https://github.com/pikaz-18/pikaz-shell/issues"
},
"author": "pikaz",
"license": "MIT"
}
复制代码
name为项目名称,version为项目版本,每一次发布都须要更改版本,description为项目介绍,main为项目的入口地址,咱们指定为打包出来的lib目录下的pikaz-shell.js文件,keywords为项目关键词,files为白名单,只有在白名单上的文件或文件夹才会上传至npm,咱们只须要上传打包的文件夹lib便可,减小包体积,repository为项目github的地址,bugs为github上issue的地址,author为做者,license为开源协议,通常咱们写插件选择MIT便可,这个协议规定最松,如需了解其余协议可自行搜索。
本插件也上传至npm了,若有须要,也能够直接使用哦
npm install --save -dev pikaz-shell
复制代码
下一篇文章会使用此插件来构建一个服务器上的前端自动部署功能,不再用看后端脸色或者手动更新开发环境项目啦。
若是以为有收获的话,请点个赞吧,rua