Cordova CLI 소스 분석 (5) – 플랫폼 추가
입구는 당연히 플랫폼 함수입니다.
module.exports = function platform(command, targets, callback) {
.....
};
먼저 구체적인 원본 코드를 보지 않고 다른 몇 개의 함수를 보다
(1)module.exports.supports = function(project_root, name, callback) {
이 함수는 주로 다음 단계를 수행합니다.
//전송 매개변수 확인
//플랫폼 지원 여부 판단
//최상위 디렉터리에서platforms를 얻습니다.js에서parser 매개 변수가 지정한 플랫폼 분석 파일
//플랫폼에 의존하는 SDK가 있는지 확인
/**
* Check Platform Support.
*
* Options:
*
* - {String} `name` of the platform to test.
* - {Function} `callback` is triggered with the answer.
* - {Error} `e` null when a platform is supported otherwise describes error.
*/
module.exports.supports = function(project_root, name, callback) {
// required parameters
if (!name) throw new Error('requires a platform name parameter');
if (!callback) throw new Error('requires a callback parameter');
// check if platform exists
var platform = platforms[name];
if (!platform) {
callback(new Error(util.format('"%s" platform does not exist', name)));
return;
}
// look up platform meta-data parser
var platformParser = platforms[name].parser;
if (!platformParser) {
callback(new Error(util.format('"%s" platform parser does not exist', name)));
return;
}
// check for platform support
platformParser.check_requirements(project_root, function(e) {
// typecast String to Error
e = (typeof e == 'string') ? new Error(e) : e;
// typecast false Boolean to null
e = (e) ? e : null;
callback(e);
});
};
(2)function call_into_create(target, projectRoot, cfg, id, version, callback, end) {
이 함수는 각 모바일 개발 플랫폼 SDK 환경에서 제공하는 원본 프로젝트 파일을 만드는 방법을 호출하여 프로젝트를 만듭니다.
function call_into_create(target, projectRoot, cfg, id, version, callback, end) {
var output = path.join(projectRoot, 'platforms', target);
// Check if output directory already exists.
if (fs.existsSync(output)) {
var err = new Error('Platform "' + target + '" already exists at "' + output + '"');
if (callback) callback(err);
else throw err;
} else {
// Make sure we have minimum requirements to work with specified platform
events.emit('log', 'Checking if platform "' + target + '" passes minimum requirements...');
module.exports.supports(projectRoot, target, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
} else {
// Create a platform app using the ./bin/create scripts that exist in each repo.
// Run platform's create script
var bin = path.join(cordova_util.libDirectory, target, id, version, 'bin', 'create');
//
if(target == 'wp7') bin = path.join(cordova_util.libDirectory, 'wp', id, version, 'wp7', 'bin', 'create');
if(target == 'wp8') bin = path.join(cordova_util.libDirectory, 'wp', id, version, 'wp8', 'bin', 'create');
var args = (target=='ios') ? '--arc' : '';
var pkg = cfg.packageName().replace(/[^\w.]/g,'_');
var name = cfg.name();
var command = util.format('"%s" %s "%s" "%s" "%s"', bin, args, output, pkg, name);
events.emit('log', 'Running bin/create for platform "' + target + '" with command: "' + command + '" (output to follow)');
shell.exec(command, {silent:true,async:true}, function(code, create_output) {
events.emit('log', create_output);
if (code > 0) {
var err = new Error('An error occured during creation of ' + target + ' sub-project. ' + create_output);
if (callback) callback(err);
else throw err;
} else {
require('../cordova').prepare(target, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
} else {
createOverrides(projectRoot, target);
end(); //platform add is done by now.
// Install all currently installed plugins into this new platform.
var plugins_dir = path.join(projectRoot, 'plugins');
var plugins = cordova_util.findPlugins(plugins_dir);
var parser = new platforms[target].parser(output);
plugins && plugins.forEach(function(plugin) {
events.emit('log', 'Installing plugin "' + plugin + '" following successful platform add of ' + target);
plugman.install(target, output, path.basename(plugin), plugins_dir, { www_dir: parser.staging_dir() });
});
}
});
}
});
}
});
}
}
(3) 플랫폼으로 돌아가는 함수
module.exports = function platform(command, targets, callback) {
var projectRoot = cordova_util.isCordova(process.cwd());
// .cordova , cordova , ; false
if (!projectRoot) {
var err = new Error('Current working directory is not a Cordova-based project.');
if (callback) callback(err);
else throw err;
return;
}
var hooks = new hooker(projectRoot);
if (arguments.length === 0) command = 'ls';// , ls
if (targets) {
if (!(targets instanceof Array)) targets = [targets];// targets
targets.forEach(function(t) {
if (!(t in platforms)) {
var err = new Error('Platform "' + t + '" not recognized as core cordova platform.');
if (callback) return callback(err);
else throw err;
}
});
} else {
if (command == 'add' || command == 'rm') {
var err = new Error('You need to qualify `add` or `remove` with one or more platforms!');
if (callback) return callback(err);
else throw err;
}
}
var xml = cordova_util.projectConfig(projectRoot);// /www/config.xml
var cfg = new cordova_util.config_parser(xml);// xml
var opts = {
platforms:targets
};
switch(command) {
case 'add':
var end = n(targets.length, function() {
hooks.fire('after_platform_add', opts, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
} else {
if (callback) callback();
}
});
});
hooks.fire('before_platform_add', opts, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
} else {
var config_json = config.read(projectRoot);
targets.forEach(function(t) {
lazy_load.based_on_config(projectRoot, t, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
} else {
if (config_json.lib && config_json.lib[t]) {
call_into_create(t, projectRoot, cfg, config_json.lib[t].id, config_json.lib[t].version, callback, end);
} else {
call_into_create(t, projectRoot, cfg, 'cordova', platforms[t].version, callback, end);
}
}
});
});
}
});
break;
case 'rm':
case 'remove':
var end = n(targets.length, function() {
hooks.fire('after_platform_rm', opts, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
} else {
if (callback) callback();
}
});
});
hooks.fire('before_platform_rm', opts, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
} else {
targets.forEach(function(target) {
shell.rm('-rf', path.join(projectRoot, 'platforms', target));
shell.rm('-rf', path.join(cordova_util.appDir(projectRoot), 'merges', target));
var plugins_json = path.join(projectRoot, 'plugins', target + '.json');
if (fs.existsSync(plugins_json)) shell.rm(plugins_json);
end();
});
}
});
break;
case 'ls':
case 'list':
default:
var platforms_on_fs = cordova_util.listPlatforms(projectRoot);
hooks.fire('before_platform_ls', function(err) {
if (err) {
if (callback) callback(err);
else throw err;
} else {
events.emit('results', (platforms_on_fs.length ? platforms_on_fs : 'No platforms added. Use `cordova platform add <platform>`.'));
hooks.fire('after_platform_ls', function(err) {
if (err) {
if (callback) callback(err);
else throw err;
}
});
}
});
break;
}
};
구조가 비교적 간단하고 매개 변수 검사를 한 다음에 서로 다른 매개 변수에 따라 서로 다른 동작을 수행한다. 유일한 설명은 switch 함수에 나타난
var end = n(targets.length, function() {
hooks.fire('after_platform_add', opts, function(err) {
if (err) {
if (callback) callback(err);
else throw err;
} else {
if (callback) callback();
}
});
});
이 함수는 node의 nCallbacks 플러그인을 사용합니다.https://npmjs.org/package/ncallbacks
공식 문서 설명은functionthatexecutesntimes입니다. 위의 코드에서 end 함수는 targets만 실행된다는 뜻입니다.length회, targets를 초과합니다.length 회 재호출end, 그 내부 함수도 다시 실행되지 않습니다. 사실은 횟수를 제한하여 플랫폼 목록이 비어 있는 후에도 잘못 실행하지 않도록 합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
iOS-IPA-ReleaseiOS 기업 개발 계정 서버에 ipa 발표 게시 전에 필요한 문서: 1. https 서버, 반드시 https(본 문서는 https 인증서 관련 지식을 소개하지 않습니다) 2. 포장된 ipa 파일 3. html 페이지...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.