Cordova CLI源码分析(三)——初始化
本部分主要涉及以下三个文件
1 cli.js
2 cordova.js
3 events.js
通过前一篇package.json的分析,可以知道,当命令行执行cordova相关命令时,首先调用main参数指向的cordova.js文件,加载模块的相关信息,把内部接口暴露出来,起到初始化作用,方便后续模块内部调用各部分接口;
然后bin 指向的./bin/cordova 文件,执行
1. .#!/usr/bin/env node
2. var CLI = require('../src/cli');
3. new CLI(process.argv);
调用 src/cli,js文件,这个文件才是真正解析命令行参数,并执行对应操作的内容;
cli.js源码
var optimist = require('optimist'),
cordova = require('../cordova'),
plugman = require('plugman'),
platforms = require("../platforms");
module.exports = function CLI(inputArgs) {
//inputArgs参数是process.argv,命令行参数数组
//第一个元素是node,第二个元素是脚本文件名,第三个元素开始每个元素是运行参数
//所以假设用户输入的是:cordova create hello hellotest com.jinkai.hellotest
//process.argv输出结果是:node cordova create hello hellotest com.jinkai.hellotest
args = optimist(inputArgs)
.boolean('d') //boolean判断命令行参数中是否存在d,如果有args.d返回true,否则false
.boolean('verbose')
.boolean('v')
.boolean('version')
.argv;//args.argv 返回命令参数
if (args.v || args.version) {
return console.log(require('../package').version);
}
//arrayObject.slice(start,end) 方法可从已有的数组中返回选定的元素
//start 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
//end 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
//返回值:返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素
var tokens = inputArgs.slice(2), //inputArgs从数组中提取第三个元素(包含第三个)到最后,产生一个新数组
opts = {
platforms: [],
options: [],
verbose: (args.d || args.verbose)
},
cmd;
// provide clean output on exceptions rather than dumping a stack trace
process.on('uncaughtException', function(err){
if (opts.verbose) {
console.error(err.stack);
} else {
console.error(err);
}
process.exit(1);
});
cordova.on('results', console.log);
if (opts.verbose) {
cordova.on('log', console.log);
cordova.on('warn', console.warn);
plugman.on('log', console.log);
plugman.on('warn', console.warn);
//Remove the corresponding token
//删除token数组中的标识符,即-d ,--verbose这类参数
if(args.d && args.verbose) {
tokens.splice(Math.min(tokens.indexOf("-d"), tokens.indexOf("--verbose")), 1);
} else if (args.d) {
tokens.splice(tokens.indexOf("-d"), 1);
} else if (args.verbose) {
tokens.splice(tokens.indexOf("--verbose"), 1);
}
//arrayObject.splice(index,howmany,element1,.....,elementX) 函数
//index 必需。规定从何处添加/删除元素。
//howmany 必需。规定应该删除多少元素。必须是数字,但可以是 "0"。
//返回值:如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组
}
cmd = tokens && tokens.length ? tokens.splice(0,1) : undefined;
if (cmd === undefined) {
return cordova.help();
}
if (cordova.hasOwnProperty(cmd)) {
if (cmd == 'emulate' || cmd == 'build' || cmd == 'prepare' || cmd == 'compile' || cmd == 'run') {
// Filter all non-platforms into options
tokens.forEach(function(option, index) { //此处使用forEach遍历元素,不应使用for循环,避免node异步IO机制带来的问题
if (platforms.hasOwnProperty(option)) {
opts.platforms.push(option);
} else {
opts.options.push(option);
}
});
cordova[cmd].call(this, opts);
} else if (cmd == 'create' || cmd == 'serve') {
cordova[cmd].apply(this, tokens);
} else {
// platform/plugins add/rm [target(s)]
var invocation = tokens.slice(0,1); // this has the sub-command, i.e. "platform add" or "plugin rm"
var targets = tokens.slice(1); // this should be an array of targets, be it platforms or plugins
invocation.push(targets);
cordova[cmd].apply(this, invocation);
}
} else {
throw new Error('Cordova does not know ' + cmd + '; try help for a list of all the available commands.');
}
}
源码中加入了必要的注释;
这段代码的主要作用就
1)提取参数,然后调用针对命令参数,分别调用不同接口函数;
2)Log和debug信息输出设置判断
3)栈崩溃信息的美化处理
再来看一下cordova.js文件
var cordova_events = require('./src/events'),
prepare = require('./src/prepare'),
platform = require('./src/platform'),
run = require('./src/run'),
hooker = require('./src/hooker'),
util = require('./src/util'),
path = require('path'),
fs = require('fs'),
compile = require('./src/compile');
var off = function() {
cordova_events.removeListener.apply(cordova_events, arguments);
};
var emit = function() {
cordova_events.emit.apply(cordova_events, arguments);
};
module.exports = {
help: require('./src/help'),
config: require('./src/config'),
create: require('./src/create'),
platform: platform,
platforms: platform,
prepare: prepare,
compile: compile,
run: run,
ripple: require('./src/ripple'),
emulate: require('./src/emulate'),
plugin: require('./src/plugin'),
plugins: require('./src/plugin'),
serve: require('./src/serve'),
on: function() {
cordova_events.on.apply(cordova_events, arguments);
},
off: off,
removeListener:off,
removeAllListeners:function() {
cordova_events.removeAllListeners.apply(cordova_events, arguments);
},
emit: emit,
trigger: emit,
build: require('./src/build')
};
这段代码作用主要有三个:
1)包含依赖文件 require(....)函数部分
2)对node.js事件机制的包装,on 和off两个函数对应绑定事件和移除事件,emit 发射事件,其中cordova_events = require('./src/events') ,调用events.js
var events = require('events');
var emitter = new events.EventEmitter();
module.exports = emitter;
3)Module.exports中暴露出必要的参数接口
Cordova CLI源码分析(三)——初始化的更多相关文章
- Cordova CLI源码分析(四)——创建工程
在第一篇分析我们曾经举例,创建一个新工程, cordova create hello hellotest com.xxx.hellotest cli.js文件分析命令行参数后,会走到 else if ...
- Cordova CLI源码分析(一)——简介
本系列文章分析基于node.js的命令行工具Cordova CLI,所以如果对node.js基础不是很了解,建议参考http://nodejs.gamesys.net/node-js提供的基础教程 文 ...
- Cordova CLI源码分析(二)——package.json
每个包需要在其顶层目录下包含一个package.json文件,该文件不仅是包的说明,也影响npm安装包时的配置选项 更多参数详见参考文档https://npmjs.org/doc/json.html ...
- SpringMVC源码分析--容器初始化(三)HttpServletBean
在上一篇博客springMVC源码分析--容器初始化(二)DispatcherServlet中,我们队SpringMVC整体生命周期有一个简单的说明,并没有进行详细的源码分析,接下来我们会根据博客中提 ...
- SpringMVC源码分析--容器初始化(四)FrameworkServlet
在上一篇博客SpringMVC源码分析--容器初始化(三)HttpServletBean我们介绍了HttpServletBean的init函数,其主要作用是初始化了一下SpringMVC配置文件的地址 ...
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
- tomcat源码分析(三)一次http请求的旅行-从Socket说起
p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...
- SpringMVC源码分析--容器初始化(五)DispatcherServlet
上一篇博客SpringMVC源码分析--容器初始化(四)FrameworkServlet我们已经了解到了SpringMVC容器的初始化,SpringMVC对容器初始化后会进行一系列的其他属性的初始化操 ...
- springMVC源码分析--容器初始化(二)DispatcherServlet
在上一篇博客springMVC源码分析--容器初始化(一)中我们介绍了spring web初始化IOC容器的过程,springMVC作为spring项目中的子项目,其可以和spring web容器很好 ...
随机推荐
- 基于Hadoop2.0、YARN技术的大数据高阶应用实战(Hadoop2.0\YARN\Ma
Hadoop的前景 随着云计算.大数据迅速发展,亟需用hadoop解决大数据量高并发访问的瓶颈.谷歌.淘宝.百度.京东等底层都应用hadoop.越来越多的企 业急需引入hadoop技术人才.由于掌握H ...
- No matching code signing identity found
真机调试过程中弹出这个问题,网上找到的解决的方法,记录一下. .... 弄完这些步骤之后,上面多出一个 IOS disturbution.所以出现这个问题的解决办法应该是设置的证书没有刷新到本地所致.
- 华为OJ培训主题 比赛统计
题目例如以下: 比赛情况统计 有一个游戏平台,各个參赛队伍(以唯一的TeamID来标识)之间进行单循环的对抗赛,两个队伍之间仅仅举行一场比赛,比赛以得分的多少定胜负.须要完毕一个统计赛况的程序,可以随 ...
- 采购订单me22n 或者me21n增强 (点击保存和回车)
IF_EX_ME_PROCESS_PO_CUST DATA:l_header TYPE mepoheader, l_item TYPE mepoitem. DATA:lt_items TYPE pur ...
- (原创)(C#随笔)IEnumerable< ICollection < IList区别
public interface IEnumerable { IEnumerator GetEnumerator(); } 再看ICollection<T> public interfac ...
- (四)SAX方式解析XML数据
SAX方式解析XML数据 文章来源:http://www.cnblogs.com/smyhvae/p/4044170.html 一.XML和Json数据的引入: 通常情况下,每个需要访问网络的应用程 ...
- js封装的类似java StringBuilder类
使用js的时候,经常会使用字符串拼接,但是在IE6和IE7没有对+作优化,所以性能会很低,鉴于此,我封装了StringBuilder类,用于拼接字符串,直接把代码贴出来如下: function Str ...
- 数字证书, 数字签名, SSL(TLS) , SASL .
因为项目中要用到TLS + SASL 来做安全认证层. 所以看了一些网上的资料, 这里做一个总结. 1. 首先推荐几个文章: 数字证书: http://www.cnblogs.com/hyddd/ar ...
- C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET
C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...
- UVALive 5791 Candy's Candy 解题报告
比赛总结 题目 题意: 有f种口味的糖果,现在要把每颗糖果分到一些packs里面去.packs分两种: flavored pack:只有一种口味. variety pack:每种口味都有. 求满足下列 ...