来从零构建一个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

相关文章
相关标签/搜索