1. yargs #

1.1 安装 #

cnpm install yargs --save

1.2 读取命令行参数 #

hello.js

#!/usr/bin/env node
let argv = require('yargs')
    .alias('n', 'name')//还可以指定参数别名  -n的别名是--name
    .demand(['n'])//是否必填
    .default({ name: 'zhufeng' })//默认值
    .describe({ name: '你的姓名' })// 参数描述
    .boolean(['private'])
    .argv;
console.log(process.argv);
console.log(argv);
console.log('hello', argv.name);
console.log(argv._);//argv对象有一个下划线属性,可以获取非连词线开头的参数

```js
node hello.js --private  A B C
[
  'C:\\Program Files\\nodejs\\node.exe',
  'C:\\vipdata\\prepare6\\zhufeng_loader\\5.js',
  '--private',
  'A',
  'B',
  'C'
]
{
  _: [ 'A', 'B', 'C' ],
  private: true,
  name: 'zhufeng',
  n: 'zhufeng',
  '$0': '5.js'
}
hello zhufeng
[ 'A', 'B', 'C' ]
#!/usr/bin/env node
let argv = require('yargs')
    .option('n',//参数n
        {
            alias: 'name',//别名name
            demand: true,//必填
            default: 'zhufeng',//默认值
            describe: '你的姓名',//描述
            type: 'string',//参数类型
        }).usage('Usage: hello [options]')// 用法格式
    .example('hello -n zhufeng', 'hello zhufeng')//示例
    .help('h')//显示帮助 信息
    .alias('h', 'help')//显示帮助信息
    .epilog('copyright 2019')//出现在帮助信息的结尾
    .argv
console.log(process.argv);
console.log(argv);
console.log('hello', argv.name);
console.log(argv._);//argv对象有一个下划线属性,可以获取非连词线开头的参数

```js
node hello.js -n jiagou
[
  'C:\\Program Files\\nodejs\\node.exe',
  'C:\\vipdata\\prepare6\\zhufeng_loader\\6.js',
  '-n',
  'jiagou'
]
{ _: [], n: 'jiagou', name: 'jiagou', '$0': '6.js' }
hello jiagou
[]

2. Semaphore #

2.1 使用Semaphore #

let Semaphore = require('semaphore');
let semaphore = new Semaphore(2);
console.time('cost');
semaphore.take(function () {
    setTimeout(() => {
        console.log(1);
        semaphore.leave();
    }, 1000);
});
semaphore.take(function () {
    setTimeout(() => {
        console.log(1);
        semaphore.leave();
    }, 2000);
});
semaphore.take(function () {
    console.log(3);
    semaphore.leave();
    console.timeEnd('cost');
});

2.2 实现Semaphore #

class Semaphore {
    constructor(available) {
        this.available = available;
        this.waiters = [];
        this._continue = this._continue.bind(this);
    }

    take(callback) {
        if (this.available > 0) {
            this.available--;
            callback();
        } else {
            this.waiters.push(callback);
        }
    }

    leave() {
        this.available++;
        if (this.waiters.length > 0) {
            process.nextTick(this._continue);
        }
    }

    _continue() {
        if (this.available > 0) {
            if (this.waiters.length > 0) {
                this.available--;
                const callback = this.waiters.pop();
                callback();
            }
        }
    }
}

2.3 webpack中的Semaphore #

class Semaphore {
    constructor(available) {
        this.available = available;
        this.waiters = [];
        this._continue = this._continue.bind(this);
    }

+    acquire(callback) {
        if (this.available > 0) {
            this.available--;
            callback();
        } else {
            this.waiters.push(callback);
        }
    }

+    release() {
        this.available++;
        if (this.waiters.length > 0) {
            process.nextTick(this._continue);
        }
    }

    _continue() {
        if (this.available > 0) {
            if (this.waiters.length > 0) {
                this.available--;
                const callback = this.waiters.pop();
                callback();
            }
        }
    }
}

3. neo-async #

3.1 使用 #

let {forEach} = require('neo-async');
console.time('cost');
let array = [1, 2, 3];
forEach(array, function (num, done) {
    setTimeout(function () {
        console.log(num);
        done();
    }, num * 1000);
}, function (err) {
    console.timeEnd('cost');
});

3.2 实现 #

function forEach(array, iterator, callback) {
    let length = array.length;
    function done() {
        if (--length == 0)
            callback();
    }
    array.forEach((item, index) => {
        iterator(item, done);
    });
}

4.acorn #

4.1 介绍 #

ast

const ast = acorn.parse(code, options);

4.2 配置项 #

4.2 查找依赖 #

const acorn = require("acorn")
const walk = require("acorn-walk");
const escodegen = require('escodegen');
const ast = acorn.parse(`
import $ from 'jquery';
let _ = require('lodash');
`, { locations: true, ranges: true, sourceType: 'module', ecmaVersion: 8 });
let resources = [];
walk.simple(ast, {
    CallExpression(node) {
        if (
            node.type === 'CallExpression' &&
            node.callee.type === 'Identifier' &&
            node.callee.name === 'require' &&
            node.arguments.length === 1 &&
            node.arguments[0].type === 'Literal'
        ) {
            const args = node.arguments;
            resources.push({
                module: args[0].value
            })
        }
    },
    ImportDeclaration(node) {
        node.specifiers[0].local.name = 'jQuery';
        resources.push({
            module: node.source.value
        })
    }
})
console.log('resources', resources);
let result = escodegen.generate(ast);
console.log(result);