NPM - 项目中用到的包汇总

未整理的包

  • [dotenv] - 读取.env配置文件内容

awdsome npm

命令行工具: yargs

  • Github,可查看example及api
  • 基本用法:

    const argv = require('yargs').argv
    
    # 别名
    var argv = require('yargs')
    .alias('n', 'name').argv;
  • 多命令使用方法:
    参考issues,每条命令有自己的参数配置:

.command('temp', '创建基础模板文件夹', function(yargs){
  return yargs
          .option('out', {
            alias: 'O',
            describe: '当前目录输出模板名称:lsqkreport',
          })
          .option('type', {
            alias: 'T',
            describe: '模板单据类型billtype名称:JC31',
          })
          .option('node', {
            alias: 'N',
            describe: '模板节点funcnode名称:JCH00301',
          })
          .option('module', {
            alias: 'M',
            describe: '所属项目名称:JC',
          })
          .option('comp', {
            alias: 'C',
            describe: '所属项目分类:lsqkmgr',
          })
          .option('data', {
            alias: 'D',
            describe: '元数据:lsqk',
          })
          .option('tabName', {
            alias: 'T',
            describe: '子表tabname',
          })
          .option('file', {
            alias: 'F',
            describe: '配置文件',
          })
})
.command('card', '创建卡片按钮模板', function(yargs){
  return yargs
          .option('head', {
            describe: '创建卡片head按钮'
          })
          .option('body',{
            describe: '创建卡片body按钮'
          })
          .option('inner',{
            describe: '创建卡片inner按钮'
          });
})
.command('list', '创建列表按钮模板', function(yargs){
  return yargs
          .option('head', {
            describe: '创建卡片head按钮'
          })
          .option('body',{
            describe: '创建卡片body按钮'
          });
})
.help().argv;

使用时查看帮助,可选择:

ncbuild --help 
或单一命令的helo:
ncbuild card --help

glob - 获取所有文件

gulp等库都是用了glob,用做定位文件,针对文件执行操作:

var glob = require("glob")

glob("**/*.js", options, function (er, files) {
  // files 是匹配到的文件的数组.
  // 如果 `nonull` 选项被设置为true, 而且没有找到任何文件,那么files就是glob规则本身,而不是空数组
  // er是当寻找的过程中遇的错误
})

选定规则后增加option选项

glob.sync('**/*.md', {ignore: ["**/SUMMARY.md"]});

readdirp - 获取某一层级下文件(可筛选)

readdirp({ 
  root: process.cwd(), // 路径
  fileFilter: '*.js', // 需要返回的文件
  directoryFilter:['!node_modules'] // 排除的文件夹
})
  .on('data',function(entry) {
    dirAry.push(entry.path.replace(/\\/g,"/"))
  })
  .on('end',function(){
    console.log(dirAry)
  });

event-stream - 事件流

github项目中,作者第一句说到Streams are node's best and most misunderstood idea, and EventStream is a toolkit to make creating and working with streams easy.
stream流常用在文件IO,作者提出:那事件呢?是否也可以一遍流入,一遍执行,而不是都缓存在内存中,答案作者给出了这个库。使用见上边。

Normally, streams are only used for IO,
but in event stream we send all kinds of objects down the pipe.
If your application's input and output are streams,
shouldn't the throughput be a stream too?

发送邮件- Nodemailer

demo如下

'use strict';
const nodemailer = require('nodemailer');

// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
    host: 'smtp.example.com',
    port: 465,
    secure: true, // secure:true for port 465, secure:false for port 587
    auth: {
        user: 'username@example.com',
        pass: 'userpass'
    }
});

// setup email data with unicode symbols
let mailOptions = {
    from: '"Fred Foo 👻" <foo@blurdybloop.com>', // sender address
    to: 'bar@blurdybloop.com, baz@blurdybloop.com', // list of receivers
    subject: 'Hello ✔', // Subject line
    text: 'Hello world ?', // plain text body
    html: '<b>Hello world ?</b>' // html body
};

// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.log(error);
    }
    console.log('Message %s sent: %s', info.messageId, info.response);
});

node快速启动服务

npm install -g serve
serve --help
serve -p 3333

cheerio

cheerio基本demo

var cheerio = require('cheerio'),
var html = `
<h2 class="title">Hello world</h2>
<ul id="fruits">
  <li class="apple">Apple</li>
  <li class="orange">Orange</li>
  <li class="pear">Pear</li>
</ul>
`
$ = cheerio.load(html, {
  decodeEntities: false
});

// 以下按照jQuery方法即可提取元素
$('h2.title').text()

cheerio常见FAQ

  • children - 查找当前层级
  • find - 查找所有层级
  • cheerio html 方法中文字体被转换
    cheerio本身默认是转实体的
    cheerio.load(html,{decodeEntities: false}); 加个参数

  • jquery cheerio 获取元素文本内容,不包括后代
    $('.element').contents().filter(function () {
    return this.nodeType == 3;
    }).text();

request - node请求

  • GET请求
var request = require('request');
request('http://www.baidu.com?query=123', function (error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body) // Show the HTML for the baidu homepage.
  }
})
  • POST application/x-www-form-urlencoded
request.post({url:'http://service.com/upload', form:{key:'value'}}, function(error, response, body) {
    if (!error && response.statusCode == 200) {
    }
})
  • POST multipart/form-data

    var formData = {
    // Pass a simple key-value pair
    my_field: 'my_value',
    // Pass data via Buffers
    my_buffer: new Buffer([1, 2, 3]),
    // Pass data via Streams
    my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
    };
    request.post({url:'http://service.com/upload', formData: formData}, function (error, response, body) {  
    if (!error && response.statusCode == 200) {
    }
    })
  • POST application/json

    request({
    uri: smsUrl,
    method: 'POST',
    json: requestData
    }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
    console.log(body);
    }
    });

    request报错options.uri is a required argument:原因是option第一个参数不是url或uri,可以按照如下方式:

    var options = {
    url: 'https://www.domainname.com/sometext/'+ var1,
    port: 80,
    method: 'GET'
    };

npm官方解析npmrc文件使用到的库ini

config.ini文件内容如下:

; this comment is being ignored
scope = global

[database]
user = dbuser
password = dbpassword
database = use_this_database

[paths.default]
datadir = /var/lib/data
array[] = first value
array[] = second value
array[] = third value

使用:

var fs = require('fs')
  , ini = require('ini')

var config = ini.parse(fs.readFileSync('./config.ini', 'utf-8'))

config.scope = 'local'
config.database.database = 'use_another_database'
config.paths.default.tmpdir = '/tmp'
delete config.paths.default.datadir
config.paths.default.array.push('fourth value')

fs.writeFileSync('./config_modified.ini', ini.stringify(config, { section: 'section' }))

pm2 进程守护

pm2想要实现真正意义进程守护,即服务器重启后也要正常启动,需要做如下操作:
pm2官网教程

$ pm2 start app.js
$ pm2 startup
$ pm2 save

nvm 使用教程

$ nvm install 8.9.3
$ nvm list
$ nvm alias default 8.9.3 //设置默认版本8.9.3

express代理:http-proxy-middleware

var express = require('express');
var proxy = require('http-proxy-middleware');

var app = express();

app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));
app.listen(3000);

// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar 

单页应用connect-history-api-fallback

包地址
单页应用实现可以刷新,此插件核心代码是后端将请求转为index.html,后续的路由交给前端路由接管。注意需要紧随创建的app使用。

const history = require('connect-history-api-fallback');
const app = express();
app.use(history());
@2017-06-13 22:44