zoukankan      html  css  js  c++  java
  • 开始你的第一个npm脚本工具

    在实际开发中,一般刚开始一个项目或者刚接手一个项目,我们会运行 npm install 下载安装所有依赖, 在实际开发中,可能也会使用各种命令行…… 来提高我们开发的效率。
    与它相处了这么久,你真的了解 npm 这些东西吗?
     
    本篇文章会分别介绍下面几个内容:
    • package.json
    • 解析命令行参数
    • 丰富终端交互体验
    • 发布 npm 包
    • 实战--开发小程序脚手架
     
    项目背景:每次新建小程序页面要生成四个文件名相同的文件 ( .wxml、.wxss、.json  和 .js ),并且要在 app.json 的 pages 字段自动添加新页面路径, 在 .json 中写上当前页面的名字,非常的麻烦,所以~ 自己动手做一个 npm 脚本工具,一键生成重复性的文件,解放双手。
    最终,我们希望实现一个这样的效果:

    在工作目录下就会有对应的文件,并且 app.json 的 pages 字段自动添加新页面路径, 对应的 .json 也有当前页面的名字.

    package.json 

    第一步,相信大家都知道,npm init 之后,就会生成一个 package.json
    我们会在 package.json 中添加以下代码
    "repository": {
      "type": "git",
      "url": "https://github.com/beidan/nsp"
    }

    这样可以指明我的代码被托管在何处,用户可以使用 npm docs 命令打开该项目。但是如果 url 类型与 type类型不一致的话,那只会默认打开该包的 name

    类似于一些简单的字段意思,我将不会详细说明,具体的规范可以在 package.json 规范 中查看。

    在有些项目的 package.json 中,我们可能会看到下面这样的代码:

    {
      "bin": {
       "nsp": "./bin/index.js"
      },
      "scripts": {
       "precommit": "./hooks/pre-commit.js",
       "prepush": "./hooks/pre-push"
      }
    }

    bin 字段可以用来存放一个可执行的文件

    执行 npm link 命令,它将会把 nsp 这个字段复制到 npm 的全局模块安装文件夹 node_modules 内,并创建符号链接(symbolic link,软链接),也就是将 nsp 的路径加入环境变量 PATH。就可以直接在命令行中使用 nsp …… 

    scripts 在每个命令前都会执行对应命令的 pre+scriptname 脚本,每个命令结束后会执行对应买了的 post+scriptname 脚本。如果没有定义,则不会执行对应的pre ,post命令。

    解析命令行参数

    为了实现功能,我们必然需要获取到用户命令行的一些参数,比如它希望新建页面,还是新建模块…然后处理获取到的数据。那么,要怎么获取到用户输入的数据?

    我们可以使用 process.argv 拿到序列化的参数,当然,原生的处理方法都是比较麻烦的,nodejs社区里边已经有了比较成熟的命令行管理工具,比如 commander 

    好的,我们找到文章上面 bin 字段对应的可执行文件,在文件开始,我们需要告诉 shell 使用何种解释器来执行代码

    #!/usr/bin/env node   //使用env来找到node,并使用node来作为程序的解释程序。

    usr/bin/env 是一个程序,usr/bin/env node 会找到当前 PATH 中的 node 来解释后面的代码。

     
    接下来,我们对 命令行 进行一些处理
    program
        .usage('[command] [options]')  //在help中告诉用户如何使用
        .command('page [pageName]')  //定义命令行指令
        .alias('pa')                 //重命名,定义一个更短的指令
        .description('新建页面')      //描述
        .action((pageName) => {
           console.log(pageName);
        })
     // 自定义帮助信息
       .on('--help', function () {
            console.log('  Examples:');
            console.log('');
            console.log('    $ nsp page index');
            console.log('    $ nsp pa index');
            console.log();
    });
    
    program.parse(process.argv);  //解析命令行

    丰富终端交互体验

    好了,通过上面的代码,我们可以正常地获取到用户输入的内容了,但是,我们在开始某些命令之前,希望先询问下用户该页面的名称,方便写入每个页面对应的 json 里面。或者,我们希望他在做一些重要决定的时候,可以让我们控制,选择输入 y 还是 n。

    我们可以借助 inquire 这个模块轻松实现,代码如下:

    var questions = [
        {
            type: 'input',    // input, confirm, list, rawlist, expand, checkbox, password, editor
            name: 'selection',     //可以在answer用这个值获取输入的值
            message: '这个页面是做什么的?',   //命令行中询问用户
            defaultfalse,  //设置默认值,一般来说,会出现在选择中
        }
    ];
    
    inquirer.prompt(questions).then((answers, input)=> { })  //解析问题

    非常容易理解,我们先创建一个 questions ,这个 questions 可以是单选,多选,密码类型… 然后解析问题,进行处理。

    emmm…… 总感觉还少了一点什么,再用 chalk 这个美化命令行的模块。

    看官方文档非常地直观了,可以让命令行变得色彩斑斓,就不赘述了。

    发布 npm 包

    理所当然,我们需要有仓库账号才允许将包发布到仓库中,可以直接去 npm 上注册。要翻墙。

    如果已经注册了账号,可以用 npm login 登陆即可,使用命令行证明是否登陆成功。

    $ npm who i am
    beidan

    登陆成功之后,就可以发布 npm 包了 

    $ npm publish

    发布的时候,一般会有以下几个错误,可以选择性地阅读。

    1. 没有将 registry 切回最初的源。

    最初的 http://registry.npmjs.org 这个源国内用户访问非常慢,所以一开始很多人可能换成了国内淘宝的镜像:http://registry.npm.taobao.org。但是淘宝这个镜像没有开放上传的权限,因此会报这样的错误:

    解决方法,在命令行改变源

    npm set registry http://registry.npmjs.org  

    2. 每次发布都需要增加 package.json 中的 version 的版本号,更新的版本号上传的版本要大于上次。

    实战--开发小程序脚手架

    下面贴相关的代码 

    var writeFile = function (path, name, tit) {
        //在 app.json 中注册页面
        util.setAppInfo(appConfig);
    
        fileType.map((item) => {
            if (item == '.json') {
                let content = '{"navigationBarTitleText": "' + tit + '"}';
                fs.writeFile(basePath + item, content, (err)=> {
                    if (err) {
                        return console.log(err);
                    }
                });
            } else {
                fs.writeFile(basePath + item, '' ,(err)=> {
                    if (err) {
                        return console.log(err);
                    }
                });
            }
        })
    }
    
    
    var creatApp = function (path, name, tit) {
        //判断是否存在该目录
        if (fs.existsSync(path)) {
            console.log(chalk.red('该项目已存在,换个名字试试?'))
        } else {
            fs.mkdir(path, function (err) {
                if (err) {
                    console.log(err);
                    throw err;
                }
            })
            writeFile(path, name, tit)
        }
    }

    为了优化体验,用户可能没有在指定目录下执行相关的命令,那么我们应该有个友好提示。

    process.cwd()     //当前执行 node 命令时候的文件夹地址 
    __dirname          //被执行的 js 文件的地址 ——文件所在目录

    那我们可以这样判断用户是否在指定目录下

    var isCorrect  = function () {
        var baseUrl = path.resolve(__dirname, '../../'),
            curUrl = process.cwd();
    
        if(baseUrl !== curUrl) {
            console.log(chalk.red('  请在根目录下进行'));
            process.exit();
        }
    }
     
     
     
    参考资料:
    凹凸实验室前端流程工具: https://github.com/o2team/athena
  • 相关阅读:
    jquery ui draggable,droppable 学习总结
    VSCode设置网页代码实时预览
    ionic3-修改APP应用图标(icon)和APP启动界面(Splash)
    Ionic3页面的生命周期
    videogular2 在ionic3项目里报错(rxjs_1.fromEvent is not a function)
    IDEA的maven项目的netty包的导入(其他jar同)
    maven的安装与项目的创建
    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
    使用二分法查询二维整型数组的值(找到返回其坐标)
    乐观锁以及悲观锁
  • 原文地址:https://www.cnblogs.com/beidan/p/6856461.html
Copyright © 2011-2022 走看看