npm shell 首先要做一个基本的shell交互命令,基于此进行node项目开发,需要引入一些基础模块。
1 2 3 4 5 6 7 var path = require('path'); //路径中间件 var co = require('co'); //koa 异步控制 var prompt = require('co-prompt'); //接受指令信息 var program = require('commander'); var fs = require('fs-extra'); var shell = require('shelljs'); var jsonFormat = require('json-format');
引入相应的模块之后,我们开始对程序有所定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 program .version(require('./package.json').version) .usage('[command][options]') .option('-d, --description', 'Description of the module.'); program .command('init') .description('general package.json') .option('-y,--yes', 'general package.json without prompt') .action(init); program .command('install [optional...]') .description('install modules') .option('-S,--save', 'save modules as dependencies') .option('-D,--save-dev', 'save modules as dependencies') .option('-g,--global', 'save modules as global') .action(install); program.parse(process.argv);
上面利用了commander
插件进行命令行工具的初始化设定,这里预先定义了’init’与’install’命令的声明。
接下来看到函数的具体构造过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 function init(options) { co(function*() { var mypackage = {}; var isPromptMode = options.yes ? false : true; // 默认名称为当前文件夹小写 var _defaultName = path.basename(process.cwd()).toLowerCase(); // 默认入口文件为index.js var _defaultEntryPoint = 'index.js'; // var jsArr = shell.js('*.js'); 没有js文件时,有额外输出 var jsArr = shell.ls(); // 当前目录下,如果存在js文件,将找到的第一个js文件作为默认值 for (var i = 0; i < jsArr.length; i++) { if (path.extname(jsArr[i]) === '.js') { _defaultEntryPoint = jsArr[i]; break; } } var _testCommand = 'echo \"Error: no test specified\" && exit 1'; // 拼接将生成的package.json文件的绝对路径 var mypackagePath = path.resolve(process.cwd(), 'package.json'); var _inputName = '', _inputVersion = '', _inputDesc = '', _inputEntryPoint = '', _inputTestCommand = '', _gitRepository = '', _keywords = '', _author = '', _license = '', _confirm = ''; if (isPromptMode) { console.log('This utility will walk you through creating a package.json file, can overrides some common params'); _inputName = yield prompt('name: (' + _defaultName + ')'); _inputVersion = yield prompt('version:(1.0.0)'); _inputDesc = yield prompt.multiline('description: '); _inputEntryPoint = yield prompt('entry point: (' + _defaultEntryPoint + ')'); _inputTestCommand = yield prompt('test command: '); _gitRepository = yield prompt('git repository: '); _keywords = yield prompt('keywords: '); _author = yield prompt('author: '); _license = yield prompt('license: (MIT) '); } // 处理生成package.json信息 mypackage.name = _inputName || _defaultName; mypackage.version = _inputVersion || '1.0.0'; mypackage.description = _inputDesc || ''; mypackage.main = _inputEntryPoint || _defaultEntryPoint; mypackage.scripts = {}; mypackage.scripts.test = _inputTestCommand || _testCommand; if (_gitRepository) { mypackage.repository = {}; mypackage.repository.type = 'git'; mypackage.repository.url = _gitRepository; } mypackage.keywords = _keywords.split(' ') || []; mypackage.author = _author || ''; mypackage.license = _license || 'ISC'; if (isPromptMode) { console.log('Aborted'); console.log(jsonFormat(mypackage) + '\n'); _confirm = yield prompt.confirm('Is this ok?(y|n)'); if (!_confirm) { console.log('Aborted'); process.exit(); } } else { console.log('Wrote to ' + mypackagePath + '\n'); console.log(jsonFormat(mypackage) + '\n'); } // 将信息写入package.json文件 fs.outputJsonSync(mypackagePath, mypackage); /*确保入口文件存在唯一的npm init方法*/ fs.ensureFileSync(mypackage.main); process.exit(); }); }
install方法同理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function install(optiontag, options) { var _command = ['npm', 'install']; _command = _command.concat(optiontag); if (options.global) { _command.push('-g'); } else if (options.save) { ensurePackageJsonExist(); _command.push('--save'); } else if (options.saveDev) { ensurePackageJsonExist(); _command.push('--save-dev'); } shell.exec(_command.join(' '), { async: true }); } function ensurePackageJsonExist() { if (!fs.existSync(path.join(process.cwd(), 'package.json'))) { console.log('在当前文件下找不到\"package.json\"文件, 建议先init'); program.help(); } }
整个流程为定义=>初始化装载=>拼接参数=>指定命令对应关系
即可达到发包时以当前目录为基准的 path –option的命令模式。
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏