如何写一个npm 命令插件

1,099 阅读4分钟

这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战

背景

学习前端三个月了,准备刷刷面试题,总结总结,一天几道面试题,向大厂进军。

一天,有个同学问我,我想写一个工具包,发布到npm上,然后直接npm安装包,直接命令,就可以触发这个包的功能。

这个怎么写啊? 其实就是一个npm工具包!

“别慌,我来教你,包学包会”--我说

读取Lottie.json 动画中的所有图片地址

  1. 首先我们应该明白一个简单的npm 包必要的几个文件。
  2. 配置工具包的使用命令
  3. 代码读取用户交互命令输入
  4. 根据用户输入,实现工具包的功能。

npm 工具包必要文件

  1. package.json
  2. README.md
  3. index.js

简单吧,其实三个文件就可以搞定一个npm包。

package.json 主要用来配置你工具包的名称,版本,以你命令,工具包依赖等。 我们执行 npm init 就可以了。根据提示填写会自动生成package.json文件。

README.md 为什么需要这个文件呢,其实这个文件可有可无,但是我们作为一个工具包,是要提供给别人使用的,这个就相当于使用说明书,不然你的工具包再怎么牛,别人不会使用,也只能冰封了。

index.js 就是我们的代码文件了,我们编写的代码是运行在node环境,所以要在首行加上:

#!/usr/bin/env node

开搞

  1. 我们使用npm init 生成了package.json文件
    {
        "name": "lottie-extract-assets",
        "version": "1.0.3",
        "description": "根据lottie配置文件,提取lottie的json文件中图片,输出配置",
        "main": "index.js",
        "scripts": {
            "lottieExtract": "node ./index.js"
        },
        "bin": {
            "lottieExtract": "./index.js"
        },
        "repository": {
            "type": "git",
            "url": "https://github.com.cnpmjs.org/qyjandroid/lottie-extract-assets.git"
        },
        "keywords": [
            "lottie",
            "资源提取",
            "图片提取"
        ],
        "author": "quanyj",
        "license": "ISC",
        "dependencies": {
            "commander": "^7.2.0",
            "inquirer": "^8.0.0",
            "request": "^2.88.2"
        }
    }

这里注意一个配置:bin 字段

bin 字段用于配置别人执行什么命令触发我们的脚本。

比如我这里配置:

    "bin": {
            "lottieExtract": "./index.js"
        },

这个时候,别人使用我的工具包的时候,只需要在命令行输入:lottieExtract 就会执行我的工具包脚本。

  1. 编写功能index.js

由于我们要提取lottie.json文件,我们和用户进行交互,是提取哪个json文件,以及输出什么文件名或者保存到哪个目录,这些都是需要交互的,所以这里我们需要用到两个库:

  • Commander.js 完整的 node.js 命令行解决方案
  • Inquirer.js 一组通用的交互式命令行用户界面。

首先我们安装这两个工具包:

    cnpm install commander inquirer -D

我们代码实现功能步骤:

  1. 我们首先在当前安装包的环境下找默认 lottie-extract-assets.json 文件。
  2. 如果没有找到,我们就提示用户输入交互命令,根据用户输入的配置去实现功能。
  3. 如果找到了lottie-extract-assets.json 就解析生成默认配置,根据配置实现功能。

代码实现:

    #!/usr/bin/env node
    //文件操作使用fs
    const fs = require('fs');
    const request = require('request');
    const path = require('path');
    const program = require('commander');
    const inquirer = require('inquirer');
    const cwd = process.cwd();

    //默认读取的配置文件
    const defaultConfigJsonName="lottie-extract-assets.json";
    const defaultConfigJson =path.join(cwd,defaultConfigJsonName);
    console.log("读取配置文件:",defaultConfigJson);
    //读取默认配置文件
    readJsonFile(defaultConfigJson).then((result)=>{
        //如果配置文件存在,提取配置文件
        if(result){
            startAssetsExtract(result);
        }else{
            //默认配置文件不存在,用户执行交互操作,生成配置文件
            console.log(defaultConfigJsonName+"文件不存在,请按照以下提示操作")
            program.version('v' + require('./package.json').version, '-v, --version')
                .action(() => {
                        inquirer.prompt([
                            {
                                type:'input',
                                name: 'configPath', 
                                message: '请输入LottieConfig文件path:(例如:src/lottieConfig.json)',
                                validate:val=>{
                                    if (fs.existsSync(val)) {
                                        return true;
                                    }
                                    return '文件不存在,请输入正确文件path'
                                }
                            },
                            {
                                type:'input',
                                name: 'outFileName',
                                message: '请输入输出资源文件名称:(例如:lottie-assets.js)',
                            },
                            {
                                type:'input',
                                name: 'to',
                                message: '请输入输出资源文件保存目录:(例如:dist)'
                            },
                            {
                                type:'input',
                                name: 'globalName',
                                message: '请输入全局访问提取资源对象:(例如:window._config)'
                            },
                            {
                                type:'rawlist',
                                message:'图片资源是否生成绝对路径',
                                name:'absPath',
                                choices:[
                                    {
                                        key:"yes",
                                        name:"是",
                                        value:1,
                                        checked: true // 默认选中
                                    },
                                    {
                                        key:"no",
                                        name:"否",
                                        value:2,
                                    }
                                ]
                            }


                        ]).then(async(answers)  =>  {
                            extractAssets(answers,()=>{});
                        }).catch((e)=>{
                            console.log("错误信息:",e);
                        })

                });
            program.parse(process.argv);
        }
    });

image.png

image.png

后续就是我们怎样去根据配置文件,来提取json中的内容,生成图片url。

这里由于我们读取的配置文件中lottieConfig.json是一个网络json,所以我们需要请求网络:

image.png

我们来安装request 来请求网络

    cnpm install request -D

//请求网络代码

      /**
     * 
     * 
     * 请求lottie json文件
     * @memberOf LottieExtractAssetsPlugin
     */
   function requestLottie(url,isAbsPath){
       return new Promise((resolve,reject)=>{
          request(url,  (error, response, body)=> {
              if (!error && response.statusCode == 200) {
                try{
                  const lottieData=JSON.parse(body);
                  const result= lottieParse(lottieData,url,isAbsPath);
                  resolve(result);
                }catch(e){
                    console.log(e);
                }
              }else{
                  reject(url+"==失败");
              }
            })
        })
      
    }

完整代码已上传githublottie-extract-assets

npm 发包

  1. npm login 登录

  2. npm publish 发布上传

这样我们的工具包即可以使用了。

结语

一步一步慢慢来,踏踏实实把活干!