在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 嵌入式/ Cordova CLI
Cordova CLI
CordovaLib 概要
cordova.js 概要
cordova.js 事件通道 pub/sub
cordova.js 模塊系統(tǒng) require/define
cordova.js 導(dǎo)入、初始化、啟動(dòng)、加載插件
cordova.js 本地交互 JS<->Native

Cordova CLI

(1)Node.js 的使用

Cordova CLI 基于 node.js,所以有必要知道 nodejs 最基本的知識(shí)。

Js 代碼

// define:1個(gè)module1個(gè)js文件
exports.printFoo = function(){ return "foo" }
// import
var foo = require('./foo.js');
// call
console.log(foo.printFoo());

引用

node main.js

(2)2個(gè)重要的路徑

  • C:\Documents and Settings\RenSanNing\Application Data\npm\node_modules\cordova
  • C:\Documents and Settings\RenSanNing.cordova\lib (以下簡(jiǎn)稱 LIB_ROOT)

最新源碼可以從 Github 下載,目前穩(wěn)定版是3.4。
https://github.com/apache/cordova-cli
https://github.com/apache/cordova-android

(3)輸入命令到執(zhí)行完的過(guò)程

安裝完 Nodejs 后,npm 的路徑就被放到了環(huán)境變量 PATH 中。

引用

C:\Documents and Settings\RenSanNing\Application Data\npm

以下簡(jiǎn)稱 NPM_ROOT,安裝完 Cordova 后,在這個(gè)文件夾下有:

  • cordova.cmd(windows batch)
  • cordova(linux shell)

所以在輸入 cordova cli 命令時(shí),入口就是這兩個(gè)文件,以下以 cordova.cmd 為例說(shuō)明。

a) 輸入命令(根據(jù)不同的命令處理不同,這里以添加平臺(tái)支持為例)

引用

cordova platform add android

b) 執(zhí)行/cordova.cmd

引用

node "%~dp0\node_modules\cordova\bin\cordova" %*

其中%~dp0代表的是 batch 文件所在路徑,比如執(zhí)行 C:\bat_files\example.bat,那么%~dp0 就是 C:\bat_files\。這里就是指 NPM_ROOT。類似 shell 的$0就是 Windows 下 batch 文件中獲取參數(shù)的一種方式,可以在命令行窗口執(zhí)行“for /?”可以查看詳細(xì)說(shuō)明。啟動(dòng) node 執(zhí)行 cordova(nodejs)文件,并把所有參數(shù)傳給它。(%*:輸入的所有參數(shù))

c) 執(zhí)行 cordova(nodejs)

路徑:\node_modules\cordova\bin
nodejs文件:cordova
addTs()函數(shù)是打印執(zhí)行時(shí)間,默認(rèn)未開啟,所以只要代碼是:

Js 代碼

var CLI = require('../src/cli');
new CLI(process.argv);

****cordova.cmd 作用和 npm 文件夾下的 cordova.cmd 一樣,%~dpn0 代表帶路徑的 batch 文件名。

d) 進(jìn)入\node_modules\cordova\src\cli.js d.1)// 導(dǎo)入 node_modules\cordova\cordova.js var cordova = require('../cordova');
-> // 導(dǎo)入node_modules\cordova\src\util.js
-> var cordova_util = require('./src/util');
-> // 通過(guò) addModuleProperty()方法加載不同命令的(比如這里的 platform)代碼
-> addModuleProperty(module, 'platform', './src/platform', true);
d.2)對(duì)輸入?yún)?shù)進(jìn)行解析提取
d.3)根據(jù)不同命令執(zhí)行 cordova.raw[cmd].call();
比如調(diào)用 platform()方法。

e) 進(jìn)入\node_modules\cordova\src\platform.js

Js 代碼

function platform(command, targets) {
  // 驗(yàn)證當(dāng)前文件夾是否是Cordova-based project
  var projectRoot = cordova_util.cdProjectRoot();
  // 獲取Hooks文件
  var hooks = new hooker(projectRoot);
  // ...
  // 調(diào)用相應(yīng)的方法(比如:add)******
  add(hooks, projectRoot, targets, opts)
}

Js 代碼

function add(hooks, projectRoot, targets, opts) {
  // 讀入config.xml
  var xml = cordova_util.projectConfig(projectRoot);
  var cfg = new ConfigParser(xml);

  // 執(zhí)行before_platform_add的Hook
  hooks.fire('before_platform_add', opts)

  // 獲取libDir的目錄即: <LIB_ROOT>\android\cordova\3.4.0
  lazy_load.based_on_config(projectRoot, t)
  // 調(diào)用Android SDK******
  call_into_create(t, projectRoot, cfg, libDir, template, copts)

  // 執(zhí)行after_platform_add的Hook
  hooks.fire('after_platform_add', opts);
}

Js 代碼

function call_into_create(target, projectRoot, cfg, libDir, template_dir, opts) {
  // ...

  // 檢查平臺(tái)依賴***0***
  module.exports.supports(projectRoot, target)

  var bin = path.join(libDir, 'bin', 'create');

  // 調(diào)用bat創(chuàng)建project***1***
  superspawn.spawn(bin, args, opts || { stdio: 'inherit' })

  // 調(diào)用prepare
  require('../cordova').raw.prepare(target);

  // 把merges文件夾下的文件覆蓋過(guò)去
  createOverrides(projectRoot, target);

  // 通過(guò)plugman安裝plugins下的所有插件***2***
  plugman.raw.install(target, output, path.basename(plugin), plugins_dir);
}

0

Js 代碼

function supports(project_root, name) {、
  // 平臺(tái)配置解析文件 <NPM_ROOT>\node_modules\cordova\platforms.js
  // 具體Android在:src\metadata\android_parser
  var platforms = require('../platforms');
  var platformParser = platforms[name].parser;

  // 檢查平臺(tái)依賴lib是否存在
  platformParser.check_requirements(project_root);
}

1

進(jìn)入 \android\cordova\3.4.0\bin
create.bat

引用

SET script_path="%~dp0create" 
node %script_path% %*

create(nodejs)

Js 代碼

var create = require('./lib/create');
create.createProject(args._[0], args._[1], args._[2], args._[3], args['--shared'], args['--cli']).done();

進(jìn)入 \android\cordova\3.4.0\bin\lib
create.js
說(shuō)是創(chuàng)建其實(shí)大部分都是從 libdir 拷貝過(guò)來(lái)的,執(zhí)行了一下“android update project”。

引用

C:\Documents and Settings\RenSanNing\.cordova\lib\android\cordova\3.4.0

Js 代碼

exports.createProject = function(project_path, package_name, project_name, project_template_dir, use_shared_project, use_cli_template) {
  // ...

  // 檢測(cè)Ant(ant -version),Java(java -version),Android(android list targets)
  check_reqs.run();

  // 前邊有很多Copy文件的準(zhǔn)備工作,其中最重要的cordova.js就是從以下路徑Copy過(guò)來(lái)的。
  // <LIB_ROOT>\android\cordova\3.4.0\framework\assets\www\cordova.js

  // 這里就是創(chuàng)建Android工程的具體實(shí)現(xiàn)
  // cmd:android update project --subprojects --path "platforms\android" --target android-19 --library "CordovaLib"
  // CordovaLib工程也是從<LIB_ROOT>\android\cordova\3.4.0\frameworkCopy過(guò)去的
  // target_api取得是<LIB_ROOT>\android\cordova\3.4.0\framework\project.properties的target=android-19
  runAndroidUpdate(project_path, target_api, use_shared_project);
}

2

進(jìn)入 \node_modules\cordova\node_modules\plugman
plugman.js

進(jìn)入 \node_modules\cordova\node_modules\plugman\src
install.js

Js 代碼

function installPlugin(platform, project_dir, id, plugins_dir, options) {
  //...
  // 這里就是解析plugin.xml后安裝plugin的具體實(shí)現(xiàn)
  runInstall(current_stack, platform, project_dir, plugin_dir, plugins_dir, options)
  //...
}

Js 代碼

function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, options) {
  //...
  // Copy文件
  copyPlugin();
  handleInstall();
  //...
}

Js 代碼

function handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_dir, filtered_variables, www_dir, is_top_level) {
  //...
  plugman.prepare(project_dir, platform, plugins_dir, www_dir);
  //...
}

進(jìn)入 \node_modules\cordova\node_modules\plugman\src
prepare.js

Js 代碼

scriptContent = 'cordova.define("' + moduleName + '", function(require, exports, module) { ' + scriptContent + '\n});\n';

從 plugins 往\platforms\android\assets\www\plugins 下 Copy 插件 JS 代碼的時(shí)候,添加了模塊的定義,所以最終執(zhí)行的插件的 JS 和安裝的 JS 是不一樣的。

Js 代碼

// 生成cordova_plugins.js
var final_contents = "cordova.define('cordova/plugin_list', function(require, exports, module) {\n";
final_contents += 'module.exports = ' + JSON.stringify(moduleObjects,null,'    ') + ';\n';
final_contents += 'module.exports.metadata = \n';
final_contents += '// TOP OF METADATA\n';
final_contents += JSON.stringify(pluginMetadata, null, '    ') + '\n';
final_contents += '// BOTTOM OF METADATA\n';
final_contents += '});';

以上過(guò)程只是主要的處理流程,至此 Android 項(xiàng)目創(chuàng)建成功,并且以下兩個(gè) Cordova 核心的 js 也放置到了相應(yīng)的位置。

  • platforms\android\assets\www\cordova.js
  • platforms\android\assets\www\cordova_plugins.js

其他的命令各自有各自的作用,所以處理內(nèi)容不同。特別要說(shuō)的是執(zhí)行和 project 相關(guān)的命令時(shí),最終會(huì)調(diào)用到各個(gè)平臺(tái)工程下的腳本,比如:platforms\android\cordova。放在 project 下的目的除過(guò)各個(gè)平臺(tái)的腳本不一樣以外,也使該工程更獨(dú)立,只要有 Nodejs 環(huán)境即可編譯運(yùn)行。

  • prepare
  • compile(platforms\android\cordova\build)
  • build(prepare->compile)
  • run(prepare->platforms\android\cordova\run)
  • emulate(prepare->platforms\android\cordova\run) 比run多了個(gè)參數(shù)“--emulator”

參考:
http://blog.csdn.net/mociml/article/category/1409992