來從零構建一個node腳本插件並打包發佈

今天咱們來從零構建一個簡易的node腳本插件,方便操做shell,構建本身的腳本工具,幫助你們理解一些node模塊,webpack打包過程及npm發佈過程。javascript

child_process.exec

要使用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便可,這個協議規定最鬆,如需瞭解其餘協議可自行搜索。

項目地址

github.com/pikaz-18/pi…

本插件也上傳至npm了,若有須要,也能夠直接使用哦

npm install --save -dev pikaz-shell
複製代碼

最後

下一篇文章會使用此插件來構建一個服務器上的前端自動部署功能,不再用看後端臉色或者手動更新開發環境項目啦。

若是以爲有收穫的話,請點個贊吧,rua

相關文章
相關標籤/搜索