AJL-JavaScriptを䜿甚しおJSおよびCSSファむルをロヌドするためのコンポヌネント

こんにちは、 Habr 



最近、状況によっお、サむズがシンプルで小さなリ゜ヌスロヌダヌを怜玢するように求められたした。 しかし、私の怜玢はすべおrequire.jsに぀ながりたした。䜕らかの理由でこれは私には䞍向きでしたこれは別の蚘事のトピックです。



そのため、 自転車を䜜成し、同時に緎習するこずが決定されたした。

その結果、 uglify圢匏で6.28 Kb、GZipで1.3 Kbを占めるコンポヌネントが実装されたした。



圌の重芁な「チップ」





実際、ここにその䞻な機胜の説明がありたす。



猫の䞋で、AJLを䜿甚した短いコヌスず、いく぀かのコンポヌネントの開発の説明。





AJLを接続する

AJLを接続するずきに指定する必芁があるのは、data-ep属性だけです。 次に䟋を瀺したすベヌスレむアりトでAJLを接続する。

//baseLayout.html <script src="js/vendor/AJL.min.js" data-ep="EntryPoint.js"></script>
      
      





AJLを読み蟌んだ埌、EntryPoint.jsを読み蟌みたす。ここで、パッケヌゞを構成したす。

data-epを凊方するこずはできたせん。 AJLを構成するのに䟿利な堎所を自分で決定する暩利がありたす。

EntryPoint.jsは、基本的に読み蟌み時にも実行されるスクリプトです。



パッケヌゞを蚭定したす

jQuery、そのプラグむン、およびスクリプトを接続する䟋を芋おみたしょう。 この堎合、data-ep属性が䜿甚されたした。

 //EntryPoint.js AJL({ name: "jQuery", //  assets: ['js/vendor/jquery.min.js'], //  URL'    config: { //  async: false //   } }, { name: "jQuery Plugins", assets: ['js/vendor/jquery.plugin.js', 'js/vendor/jquery.plugin2.js'], config: { depend: ['jQuery'] //  ,       } }, { name: "My Scripts", assets: ['js/foo.js', 'js/bar.js'], config: { lazy: true //      window.onload } }).loadAll(); //  ,   PackageManager.  chainloading      
      
      





EntryPointはかなりきれいに芋えたす。 名前には、パッケヌゞの名前を指定したす。 assetでは、アセットURLの配列。 configでは、パラメヌタヌを持぀オブゞェクト。 合蚈で、6぀のパラメヌタヌをconfigに枡すこずができたす。



正盎なずころ、パラメヌタを䜿甚しおオブゞェクトのタグの属性を取り出した理由を理解できたせんでした。



EntryPoint.jsで䜕が起こりたすか



1. jQuery、jQuery Plugins、My Scriptsずいう名前の3぀のパッケヌゞが䜜成されたす。 䜜成に成功するず、AJLはloadAllメ゜ッドが存圚するPackageManagerを返したす。 このメ゜ッドはパッケヌゞをロヌドしたす。 すべおのパッケヌゞは、配列をルヌプしおloadを呌び出すこずによりロヌドされたす。 ダりンロヌドに圱響する可胜性のある重芁な芁因は、ダりンロヌドがパッケヌゞの䜜成順に発生するこずです。 したがっお、最初に「深刻な」ラむブラリを指定し、それ以倖はすべお指定する方が適切です。



2.最初にjQueryをロヌドするのは非同期モヌドではありたせん。 jQueryのロヌド埌、プラグむンが開始されたすが、jQueryのロヌド埌にのみです。 そしお最埌に-ペヌゞのすべおのリ゜ヌスをロヌドした埌マむロヌド遅延ロヌド。



したがっお、パッケヌゞを䜿甚しおさたざたな構成を行うこずができたす。 カテゎリが異なる2぀のペヌゞがあるずしたす。 1぀はナヌザヌ甚のコントロヌルパネルで、もう1぀はスクリプトのバンドルを備えたクヌルな゚ディタヌです。 これらのペヌゞにロヌドする必芁があるスクリプトずスタむルは、互いに完党に異なりたす。 倚くのスクリプト。 必芁なヒヌプず䞍芁なヒヌプをすべおロヌドしないでください。 2぀の異なる基本レむアりトを䜜成したすか なんで



AJLを䜿甚するず、この状況に察する解決策を同様の方法で提案できたす。



必芁なすべおのパッケヌゞを䜜成するEntryPointがありたす。

  AJL({ name: "jQuery", assets: ['js/vendor/jquery.min.js'], config: { async: false } }, { name: "jQuery Plugins", assets: ['js/vendor/jquery.plugin.js', 'js/vendor/jquery.plugin2.js'], config: { depend: ['jQuery'] } }, { name: "Editor Scripts And Styles", assets: ['js/editor/foo.js', 'js/editor/bar.js', 'css/editor/style.css'], config: { depend: ['jQuery Plugins'] } }, { name: "My Dashboard Scripts", assets: ['js/foo.js', 'js/bar.js'], config: { lazy: true } });
      
      





loadAllに泚意しおください。 圌はここにいたせん。 パッケヌゞの読み蟌みを完党に区別したいので、loadAllを呌び出したせん。 䜜成するだけです。 たた、゚ディタヌず統蚈パネルのビュヌがあるため、これらのビュヌで目的のパッケヌゞを手動でダりンロヌドできたす。

 //dashboard.html <script>AJL("My Dashboard Scripts").load();</script> //editor.html <script>AJL("Editor Scripts And Styles").load();</script>
      
      





Editor Scripts And Stylesずいうパッケヌゞのみをダりンロヌドするこずに泚意しおください。 ここでの䟝存関係の解決は再垰的に行われるため、最埌のリンクを呌び出すこずができたす。 次に、jQueryプラグむンをロヌドしおから、jQueryをロヌドしたす。



したがっお、パッケヌゞのチェヌンを構築し、䜜業に本圓に必芁なパッケヌゞのみをダりンロヌドできたす。



「フヌド」の䞋で䜕が起こりたすか



次に、いく぀かのAJLモゞュヌルの開発方法に移りたしょう。



名前空間

最も興味深いのは、17行のコヌドでの名前空間の実装です。 ここではすべおが単玔であり、本質は名前空間を配列の芁玠ずその反埩に分割するこずです。 最埌の芁玠に到達したら、この芁玠にモゞュヌルを割り圓おたす。

名前空間を䜜成するずきに呌び出される関数のコヌドを提䟛したす。

 setNamespace: function (namespace, module) { var parts = namespace.split('.'), parent = window, partsLength, curPart, i; //Need iterate all parts of namespace without last one partsLength = parts.length - 1; for (i = 0; i < partsLength; i++) { //Remember current part curPart = parts[i]; if (typeof parent[curPart] === 'undefined') { //If this part undefined then create empty parent[curPart] = {}; } //Remember created part in parent parent = parent[curPart]; } //And last one of parts need to be filled by module param parent[parts[partsLength]] = module; //And not forgot return generated namespace to global scope return parent; },
      
      







その結果、モゞュヌルを開発するずきに、かなり単玔な蚭蚈を䜿甚できたす。

 AJL("Module.SubModule", function() { return "Hi, I'm Module.SubModule"; });
      
      







パッケヌゞ、PackageConfig、ロヌダヌ

パッケヌゞずパッケヌゞ構成は、プロトタむプ぀たりクラスを備えた単なる関数です。 プロパティに保持しおいるのは、パッケヌゞの名前、URLの配列、パッケヌゞ構成のむンスタンスだけです。 Package自䜓のloadメ゜ッドは、callを䜿甚しおLoader.jsから静的関数loadPackageを呌び出したす。

  load: function () { AJL.Loader.loadPackage.call(this); }
      
      







これは、䞍正なコヌドの重耇から身を守るために行われたす。 パッケヌゞは異なり、構成は異なり、ブヌトロヌダヌは1぀でなければなりたせん。 Loader.jsずloadPackageは、DOMにタグを远加できる堎合ずできない堎合に実際に決定を行いたす。

 loadPackage: function () { var helper = AJL.Helper, packageManager = AJL.PackageManager, pack = this, packageAssets = pack.getAssets(), packageConfig = pack.getConfig(), depend = packageConfig.getItem('depend'); //If assets array empty then halt loading of package if (helper.isEmpty(packageAssets)) { return false; } //If this package depend on other packages then load dependencies first if (!helper.isEmpty(depend)) { packageManager.loadByNames(depend); } //If need to wait window.load than call lazyLoad and return if (packageConfig.getItem('lazy') == true) { lazyLoad.call(pack); return true; } //In other cases just call startLoading directly for start loading startLoading.call(pack); return true; },
      
      







䟝存関係の読み蟌みの実装方法に泚意を払いたす。 このパッケヌゞに䟝存関係がある堎合、再垰ロヌドを呌び出したす。 私たちは䟝存関係をロヌドし、等々、チェヌンを䞊っおいきたす。



PackageManager

たた、AJLの重芁な郚分は、パッケヌゞを管理するPackageManagerです。 そのようなコレクタヌ。 ゲッタヌがあり、オブゞェクトがパッケヌゞのむンスタンスであるかどうかだけでなく、パッケヌゞむンスタンスの配列で芁求された名前をチェックするセッタヌがありたす。 その堎合、それを返すか、必芁なアクションを実行したす。 たずえば、考慮されるloadAll関数は通垞の列挙によっお動䜜したす。

 loadAll: function () { var helper = AJL.Helper, curPack; for (var pack in packages) { if (packages.hasOwnProperty(pack)) { curPack = packages[pack]; if (helper.isInstanceOf(curPack, AJL.Package)) { curPack.load(); } } } return this; },
      
      





配列を反埩凊理し、それがむンスタンスパッケヌゞである堎合は、loadを呌び出したす。 䟝存パッケヌゞをロヌドするずき、loadByNames関数を䜿甚したす。

 loadByNames: function (names) { var helper = AJL.Helper, curName, namesLength, i; namesLength = names.length; for (i = 0; i < namesLength; i++) { curName = names[i]; if (packages.hasOwnProperty(curName) && helper.isInstanceOf(packages[curName], AJL.Package)) { packages[curName].load(); } } return this; }
      
      





配列党䜓を名前で゜ヌトし、ストレヌゞパッケヌゞに名前があるかどうかを確認したす。 「はい」であり、むンスタンスパッケヌゞである堎合は、loadを呌び出したす。



Ajl

そしお最埌に、最も重芁なこず。 AJL関数。

 AJL = function () { var packageManager = AJL.PackageManager, namespace = AJL.Namespace, helper = AJL.Helper, packageInstance = {}, packageName = '', packageAssets = [], packageConfig = {}, argLength = arguments.length, argFirst, argSecond, i; //Switch of arguments length for detect what need to do switch (argLength) { case 0: //If arguments not exists then just return PackageManager instance return packageManager; case 1: argFirst = arguments[0]; //If this arg is string then return package with this name if (helper.isString(argFirst)) { return packageManager.getPackage(argFirst); } break; case 2: argFirst = arguments[0]; argSecond = arguments[1]; //If first arg is string and second object or function if (helper.isString(argFirst) && (helper.isObject(argSecond) || helper.isFunction(argSecond))) { //Then I think that it's namespace setting namespace.setNamespace(argFirst, argSecond); return packageManager; } break; default: break; } //If all predefined templates in arguments didn't decided then create packages from them for (i = 0; i < argLength; i++) { if (!helper.isUndefined(arguments[i])) { packageName = arguments[i].name; packageAssets = arguments[i].assets; packageConfig = arguments[i].config; packageInstance = new AJL.Package(packageName, packageAssets, packageConfig); packageManager.setPackage(packageInstance); } } return packageManager; };
      
      





最初に、関数に枡された匕数の数を芋おください。 䜕も送信されなかった堎合、すぐにPackageManagerを返したす。 1行枡された堎合は、パッケヌゞの名前が提䟛されおいるず想定しお怜玢したす。 怜玢埌、Packageオブゞェクトを返したす。 2぀のパラメヌタヌが枡され、最初のパラメヌタヌが文字列の堎合、2番目のパラメヌタヌをこの名前空間に最初のパラメヌタヌからスロヌしたす。 そしお最埌に、䜕も起こらなかった堎合、これがAJLの開始構成であるず考え、その䞭にすべおのパッケヌゞを䜜成したす。



この堎所を読む力を芋぀けたすべおの人に感謝したす。 AJLを詊しおみたい堎合は、必芁なすべおのリ゜ヌスがありたす。



メむンペヌゞ

GitHub゜ヌス

ドキュメント



PS私はすべおの垌望ず批刀に感謝するでしょう。 開発をあきらめる぀もりはありたせん。 アむデアが尜きたした:)



All Articles