摘要:我想自己可以嘗試一下寫一個低配版的模塊加載器來應付一下我這個單頁網站,當然只是大致模仿了主要功能。是這樣處理的模塊依賴,同時依賴,這種情況下的模塊函數被調用時,被傳入的是,所以需要自己在里面手動一下。
Contents
前言
回顧RequireJs的基本用法
實現原理
使用方法
總結
前言前段時間一直想用單頁開發技術寫一個自己的個人網站(使用es2015),寫了一部分之后,發現單頁應用因為只有一個頁面,所以第一次加載index.html時就要下載所有js文件,并且為了好管理各個部分的狀態,需要劃分頁面的各個功能區為各個模塊,es2015本身是不支持一些模塊規范的(比如AMD、CMD、CommonJs等),所以只能這樣模擬實現:
// global var spa = (function(){...})(); // module blog spa.blog = (function(){ ... return { do1: do1, do2: do2, }; })(); // module model spa.model = (function(){...})(); // module shell spa.model = (function(){...})();
并且各個模塊之間又存在一些依賴關系,在index.html里面寫script標簽來載入模塊時需要寫很多個,同時也要根據依賴關系來確定書寫順序,頁面邏輯混亂,如下:
之前用過RequireJs(一個流行的JavaScript模塊加載器),它是用同構js的架構來寫的,所以node.js環境下也能使用。我想自己可以嘗試一下寫一個低配版的js模塊加載器 requireJs-nojsja 來應付一下我這個單頁網站,當然只是大致模仿了主要功能。
回顧RequireJs的基本用法 1. 配置模塊信息requirejs.config({ baseUrl: "/javascripts", // 配置根目錄 paths: { moduleA: "a.js", moduleB: "b.js", moduleC: "c.js", }, shim: { // 配置不遵循amd規范的模塊 moduleC: { exports: "log", deps: ["moduleA"] } }, });2. 定義一個模塊
define(name, ["moduleA", "moduleB"], function(a, b){ ... return { do: function() { a.doSomething(); b.doAnother(); } }; });3. 引用一個模塊
// 引用模塊 require(["moduleA", "moduleB"], function(a, b) { a.doSomething(); b.doAnother(); });實現原理 1. config方法確定各個模塊的依賴關系
/* 記錄模塊訪問地址和模塊的依賴等信息 */ Require.config({ baseUrl: "/javascripts/", paths: { "moduleA": "./moduleA.js", // 相對于當前目錄 "moduleB": "/javascripts/moduleB.js", // 不使用baseUrl "moduleC": "moduleC.js", "moduleD": { url: "moduleD.js", deps: ["moduleE", "moduleF"], }, ... }, shim: { "moduleH": { url: "moduleH.js", exports: "log", }, } });2. 數據請求請求過程分析
(1) config配置模塊信息時并不會觸發網絡請求
(2) 在index.js主入口文件里使用require方法引用多個模塊時,根據config配置文件構造一下所有模塊的依賴分析樹。按深度優先或是廣度優先來遍歷這個依賴樹,將所有依賴按照依賴順序放進一個數組,最后進行數組去重處理,因為會出現依賴重復的情況
var dependsTree = new Tree("dependsTree"); var dependsArray = []; var dependsFlag = {}; // 解決循環依賴 // 創建樹 setDepends(depends, dependsTree); // 得到依賴數組 sortDepends(dependsArray, dependsTree); // 數據去重 arrayFilter(dependsArray); return dependsArray;
(3) 創建XHR對象異步下載數組里面的所有js文件,按照依賴順序挨個解析js代碼,解析完成后觸發回調函數,回調函數里傳入各個模塊的引用
// ajax下載代碼文件 Utils.request(url, "get", null, function(responseText){ // 暫時保存 _temp[module_name] = responseText; }); // 文件下載完成后eval解析代碼 array.map(function(jsText){ ... eval(jsText); ... }); // 調用回調函數 callback.apply(null, [dep1, dep2, dep3]);使用方法
詳細說明: github README.md
總結下載js代碼時我用了ajax來實現,所以對于跨域文件和CDN會有點問題,這個可以改成創建script標簽,指定標簽src,最后將document.head.appendChild(script),這樣來解決,其它的諸如使用XMLHttpRequest 2.0,iframe等也可以的,可以實驗一下。
解析代碼時我用了eval的方法,這個eval在JavaScript里面是眾說紛紜,可以看看這個,如果是用了上面創建script標簽的方法的話,就不用自己eval了。
發現一個bug,存在循環依賴時,代碼會報錯,還沒去解決。RequireJs是這樣處理的:模塊a依賴b,同時b依賴a,這種情況下b的模塊函數被調用時,被傳入的a是undefined,所以需要自己在b里面手動require一下a。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/92469.html
摘要:為的內置一個方法,用法和原生的事件機制一毛一樣。 前言 上兩篇Mvvm教程的熱度超出我的預期,很多碼友留言表揚同時希望我繼續出下一篇教程,當時我也半開玩笑說只要點贊超10就兌現承諾,沒想到還真破了10,所以就有了今天的文章。 準備工作 熟讀 【教學向】150行代碼教你實現一個低配版的MVVM庫(1)- 原理篇【教學向】150行代碼教你實現一個低配版的MVVM庫(2)- 代碼篇 本篇是在...
摘要:也放出地址,上面有完整工程以及在線演示地址相關閱讀教學向行代碼教你實現一個低配版的庫原理篇教學向行代碼教你實現一個低配版的庫代碼篇教學向再加行代碼教你實現一個低配版的庫設計篇教學向再加行代碼教你實現一個低配版的庫原理篇 書接上一篇: 150行代碼教你實現一個低配版的MVVM庫(1)- 原理篇 寫在前面 為了便于分模塊,和閱讀,我使用了Typescript來進行coding,總行數是正好...
摘要:模塊則負責維護,以及各個模塊間的調度思考題了解了的實現機制,你能否自己動手也試著用百來行代碼實現一個庫呢好了本教程第一部分設計篇就寫到這里,具體請移步下一篇教學向行代碼教你實現一個低配版的庫代碼篇我會用給出一版實現。 適讀人群 本文適合對MVVM有一定了解(如有主流框架ng,vue等使用經驗配合本文服用則效果更佳),雖然會用這類框架,但是對框架底層核心實現又不太清楚,或者能說出個所以然...
摘要:導言最近發掘了一個特別的網頁小游戲。于是第二天我就繼續沉迷,隨著一陣抽搐,這個游戲索然無味之后,冷靜的我決定用和開發出一個低配版。我的低配版在交互操作比較高的情況下,還是比較卡的,沒有原網頁的流暢性,可能后續考慮版本實現。 導言 最近發掘了一個特別happy的網頁小游戲--MikuTap。打開之后沉迷了一下午,導致開發工作沒做完差點就要刪庫跑路了,還好boss瞥了我一眼就沒下文了。于是...
閱讀 1026·2021-10-19 11:42
閱讀 2981·2021-09-10 10:51
閱讀 689·2021-09-09 09:33
閱讀 1769·2021-09-01 10:43
閱讀 2779·2019-08-30 12:43
閱讀 3526·2019-08-30 11:24
閱讀 2131·2019-08-30 10:56
閱讀 2785·2019-08-29 11:00