JSモジュール化が簡単に実現できます.
7530 ワード
以前は時間をかけて
単純な目標
requireJSのような機能を実現し、関連する機能
まず簡単な例をあげて、分析を行います.プロセス解析 問題分析 スクリプトをどうやって読み込むかというと、これは2つの方法を考えやすく、1つはajaxで要求し、もう1つはDom要素で追加してブラウザに読み込ませる.ajax要求はドメインをまたぐ問題があるので、Domロードの方式を採用します. モジュールのロードが完了したとどう判断しますか?scriptの は、上記の簡単な例のように、コールバック関数をモジュール 循環依存問題はこんなに難しい問題です.後に残してください. データ構造は、まずすべてのモジュールキャッシュオブジェクトを必要とし、ロードされたモジュールとローディングされているモジュールを記録する.モジュールのデータ構造を以下のように設計します. 簡単に実現する
女の子は才能がなくて、実現は主に葉のかんざしのブログの実現を参考にして、彼/彼女の実現を読んでから、自分で一回実現しました.
前の簡単な例では、ソースのDemoはここをクリックします. を します.は、 と されています. は、この に しないので、 に ります.は、 に を えます.コンソール となる.は、 のレベルのモジュールのコールバック とする.この が されます.は、 10.コンソール
これで が わります.
を す
ながら、この は を していません. もES 6とCommunJSのサイクル の を ましたが、ES 6は の を っていますので、 はありません.Common JSは に されている だけを します.
いなことに、この は があると、プログラムは を たさないために を し、 も して することはない.
:リーフ・ガフ【モジュール プログラミング】リーク・ireJSを する- なモジュール・キャリア を する. JavaScriptモジュールの ローディング はゼロからJavaScriptモジュール キャリア を する.
RequireJS
ソースコードを見に行きました.二千行ぐらいのコードですが、私の愚かさを許してくれました.本当に少し分かりません.考えてみます.やはり自分で一つ実現してからにします.単純な目標
requireJSのような機能を実現し、関連する機能
// ,
define(id, deps, factory)
// ,
require(deps, factory)
簡単な分析まず簡単な例をあげて、分析を行います.
require(['main'], function(main) {
console.log('start~~~');
main.hello();
});
deps
パラメータによって、ファイル依存スクリプトがmain.js
であることが分かりやすくなり、その後に依存スクリプトをロードし、その後に一回実行し、その結果をコールバック関数factory
のパラメータとして実行し、匿名のコールバック関数を実行すれば良い.onload
イベントで対応するモジュールローディングを判断したいです.考え方を調整して、モジュールの状態を定義して、ロードする時、状態をロード中と表記します.レコードモジュールの依存数は、モジュールのすべての依存性が全部ロードされた場合、このモジュールの対応する出力としてコールバック関数が実行され、モジュールローディングが完了します.onload
によってロード済みのコールバック関数としてどのように一時保存し、実行すればいいですか?依存するモジュールが複数ある場合は、ロードが完了するごとに、ロードが完了したかどうかを判断します.なお、この場合も、現在のモジュールのロードが完了したことを意味し、結果を返すことができます.module[name] = {
status: String, // 'loading' or 'loaded'
export: Object , //
onload: Arrray[function] //
}
女の子は才能がなくて、実現は主に葉のかんざしのブログの実現を参考にして、彼/彼女の実現を読んでから、自分で一回実現しました.
//
(function(){
//
var moduleMap = {};
//
function define(id, deps, factory){
var name;
// , factory
var params = [];
if(typeof id == "object" ){ // require(deps, factory)
factory = deps;
deps = id;
}
else{ // deine(id,deps, factory) require(id)
name = id;
}
//
var depCount = deps && deps.length;
// ,
if( !depCount || depCount == 0){
return saveModule(name, null ,factory)
}
else{
deps.forEach(function(dep, i){
//
(function(i){
// ,
loadScript(dep, function(param){
// ,
depCount--;
params[i] = param;
// 0, ,
if(depCount==0){
return saveModule(name, params, factory);
}
})
}(i))
})
}
}
function getURL(name){
if( name.indexOf('.js') < 0){
return name + '.js';
}
return name;
}
function loadScript(name, callback){
var mod = moduleMap[name];
if( mod ){
// ,
if( mod.status == 'loaded' ){
callback & callback(mod.export);
}
else{ // ,
mod.onload.push(callback);
}
}
else{
// , Dom
moduleMap[name] = {
status: 'loading',
export: null,
onload: [callback]
}
var url = getURL(name);
var el = document.createElement('script');
el.src = url;
el.id = name;
document.body.appendChild(el);
}
}
//
function saveModule(name, params, callback){
var mod = moduleMap[name];
if( mod ){
//
mod.status = 'loaded';
// , export
mod.export = callback && callback.apply(this, params);
//
while( fn = mod.onload.pop() ){
fn && fn(mod.export);
}
}
else{
// , , require(deps, factory)
callback.apply(this, params)
}
}
//
window.define = define;
window.require = define;
})()
テスト分析前の簡単な例では、ソースのDemoはここをクリックします.
requireJS Demo -- my version
// index.js
require(['main'], function(main) {
console.log('start~~~');
main.hello();
});
// main.js
define('main', [], function() {
console.log('require module: main');
return {
hello: function() {
console.log('hello main');
}
};
});
// myRequire.js
//
は を して し、 を ける.main
は、require
が であり、name
が1である.depCount
に することが かりました.main
loadScript
が されていないので、これを し、Dom を してmoduleMap['main']
をロードする.この 、moduleMap['main'] = {
status: 'loading',
export: null,
onload:[function(param){
// depCount = 1
depCount--;
params[i] = param;
// 0, ,
if(depCount==0){
return saveModule('', params, factory);
}
}]
}
main.js
は、 が したら、 の main.js
を します.define('main'...)
saveModule('main'...)
が されているので、 をmoduleMap['main']
に えて、そのコールバック を し、loaded
//
function() {
console.log('require module: main');
return {
hello: function() {
console.log('hello main');
}
};
}
export
、このときの'require module: main'
は、moduleMap['main'] = {
status: 'loaded',
export: {
hello: function() {
console.log('hello main');
}
},
onload:[function(param){
// ,
depCount--;
params[i] = param;
// 0, ,
if(depCount==0){
return saveModule('', params, factory);
}
}]
}
moduleMap['main']
を し、moduleMap['main'].onload
をパラメータmoduleMap['main'].export
はparams
に わり、 [moduleMap['main'].export]
は は1となりました. は0です.ちょうど のレベルのモジュールのdepCount
saveModule('', params, factory)
が されていないので、 にコールバック を します.すなわち、function(main) {
console.log('start~~~');
main.hello();
}
/* main = {
hello: function() {
console.log('hello main');
}
}*/
moduleMap['']
、および'start~~~'
.これで が わります.
を す
ながら、この は を していません. もES 6とCommunJSのサイクル の を ましたが、ES 6は の を っていますので、 はありません.Common JSは に されている だけを します.
いなことに、この は があると、プログラムは を たさないために を し、 も して することはない.
: