今天咱們來從零構建一個簡易的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