首先認識requirejs javascript
requirejs是個包加載器,核心功能是模塊化管理,能夠實現按需加載。 重點是明白 模塊化不是按需加載。html
模塊化的意義: 是經過代碼邏輯代表模塊之間的依賴關係和執行順序,按照模塊邏輯來分解代碼,起到配合mvc框架架構項目的做用。前端
按需加載:顧名思義 根據須要 經過模塊依賴 event事件 加載所需的模塊。java
由於作的本地混合應用,在我項目中的主要的做用是模塊化,我使用requirejs的緣由是模塊化管理,不是按需加載。jquery
backbone 配合 requirejs 架構前端方案 https://github.com/breakfriday/backboneMvc-requirejs git
backbone是很是經典的前端mvc框架 除了mvc幾乎沒有其餘功能。github
若是用backbone這一類框架 架構項目 流程: web
上圖 能夠看到編程
backbone一類框架的流程 路由驅動控制器(此處增長backboneMvc插件 backbone自己沒有控制其邏輯) 控制器驅動action action完成對應的視圖模塊與model模塊的調用,保證多個視圖模塊與model之間的通訊api
模塊結構 入口文件調用module a,module a調用module b,依次 module b 調用 c ,e , f ... 完成模板的編譯 事件的綁定 viewMode的組裝 ..... 最後生成視圖對象 render。
ctrl1 經過require([],function(){})能夠實現按需加載
define(function (require) { BackboneMVC = require("BackboneMVC") $ = require("jquery") _ = require("underscore") return function(){ BackboneMVC.namespace('MyApp.Controllers'); MyApp.Controllers.ToyController = BackboneMVC.Controller.extend({ name: 'ct1', /* the only mandatory field */ index: function () { alert("ct1") }, test1: function () { require(['model/model'],function(model){ model.init().done(function () { $(".pages").append("<div style='color: red'>test0 done " + model.name+"</div>") }).fail(function () { alert("not ok") }) this.model=undefined }.bind(this)) }, test2: function () { require(["model/model2", "view/view2"], function (model, view1) { var model = this.model = this.model || new model model.init().done(function () { view1.sucess(model.name) this.test2() }.bind(this)).fail(function () { view1.fail() }).progress(function () { view1.progess() }) }.bind(this)) } }); } });
或者 對比ctrl2流程邏輯與ctrl1相同,ctr2l使用commonjs的寫法require() 實際上是標註模塊的依賴性,進define頭,一次性加載。 requirejs 支持commonjs的語法 可是使用的是amd的協議
define(function (require) { BackboneMVC = require("BackboneMVC") $ = require("jquery") _ = require("underscore") return function(){ BackboneMVC.namespace('MyApp.Controllers'); MyApp.Controllers.ToyController = BackboneMVC.Controller.extend({ name: 'ct2', /* the only mandatory field */ index: function () { alert("this is ct2") }, test1: function () { var model=require('model/model') model.init().done(function () { $(".pages").append("<div style='color: red'>test0 done " + model.name+"</div>") }).fail(function () { alert("not ok") }) this.model=undefined }, test2: function () { var model=require("model/model2") var view1=require("view/view2") var model = this.model = this.model || new model model.init().done(function () { view1.sucess(model.name) if (model.name > 1) { this.test2() } }.bind(this)).fail(function () { view1.fail() }).progress(function () { view1.progess() }) } }); } });
這是我 requirejs + backbone 架構項目的結構。
用angular已經作了兩個項目了,這裏總結下
angular 框架執行流程: 前端方案 https://github.com/breakfriday/my-angularMvc
鬱悶的是常常有人說 angular 已經有module了還需requirejs嗎, angular的module 是命令的容器 與模塊化意思不一樣。
angualr的模塊化只是解決了 代碼邏輯的耦合性的問題,沒有經過原型鏈 class這一種方法來實現,而是經過依賴注入代替class,優勢是耦合性很散能夠很方便的拆分組合。
可是requirejs另外一部功能,控制模塊文件的加載,控制模塊文件的分割,控制模塊文件的依賴關係 這一部分邏輯是angular沒作的。
angular使用requirejs
1.打包方便, 使用requrejs 模塊化 ,編輯代碼的過程就定義了模塊之間的依賴關係,打包時候,不須要一個一個文件對照,用不到沒有依賴關係的文件不會被打包,也不會漏掉文件。
2.將script 腳本從模板頁面(針對mvc框架)抽離出來,經過js當前模塊加載須要依賴的js模塊。模板頁面只是模板。
3.能夠實現 按需加載
angular 使用命令式編程的一個框架,因此在耦合性上採用了依賴注入 ,流程與backbone一類 框架不同 ,流程執行不是經過controller model view模塊之間的調用,而是經過模板中的命令驅動。
首先認識 angular
app.js angular啓動文件
define([ 'angular', "controller/controllers", "directive/directives", "filter/filters", "angularRoute" ], function (angular,controllers,directives,filiters) { var webApp=angular.module('ccmsApp', ["ngRoute",controllers.name,directives.name,filiters.name]) })
main.js requirejs配置文件 手動啓動angular
require([ 'angular', 'script/app',"jquery"], function (angular, app) { angular.element().ready(function () { angular.resumeBootstrap([app['name']]); }); })
模塊的注入方式分爲 1. 按需加載 2.預加載 兩種方案
在個人項目中,
directive service使用預加載,優勢能夠合併壓縮成一個文件 減小http請求。且個人directive service 文件比較多不少是小文件,且各個視圖都會用到,不太好從視圖的邏輯來分割加載模塊文件。
controller 是按需加載, 優勢按需加載,由於controller 處理的就是viewModel 因此控制器文件與視圖關係是多對一,能夠從視圖的邏輯來分割加載模塊文件。缺點是由於是異步模塊,因此不進amd 依賴關係不會被打包,
須要再寫個built1.js 負責壓縮整個異步模塊的目錄
service預加載:
define(function(require){ var angular=require("angular") var accountService=require("service/script/accountService") var ngCustomListService=require("service/script/ngCustomListService") var ngCustomService=require("service/script/ngCustomService") var saveService=require("service/script/saveService") var getListService=require("service/script/getListService") var deleteService=require("service/script/deleteService") var RFMTreeService=require("service/script/RFMTreeService") var queryConfigService=require("service/script/queryConfigService") var dataTableConfigService=require("service/script/dataTableConfigService") var dataFilterConfigService=require("service/script/dataFilterConfigService") var ngRedAndBlackCustomService=require("service/script/ngRedAndBlackCustomService") var productLabelService=require("service/script/productLabelService") var ngDataImportService=require("service/script/ngDataImportService") var dataService=angular.module('dataServices', []) dataService.factory({ "ngCustomListService":ngCustomListService , "ngCustomService":ngCustomService, "saveService":saveService, "getListService":getListService, "deleteService":deleteService, "accountService":accountService, "queryConfigService":queryConfigService, "dataTableConfigService":dataTableConfigService, "dataFilterConfigService":dataFilterConfigService, "RFMTreeService":RFMTreeService, "ngRedAndBlackCustomService":ngRedAndBlackCustomService, "productLabelService":productLabelService, "ngDataImportService":ngDataImportService }) return dataService; })
按需加載:
使用angular 路由的resolve api,在路由啓動時,require 對應的ngView視圖模板頁面中所需的controller directive模塊。
經過$controllerProvider.register $compileProvider.directive $filterProvider.register $provide.provider建立controller directive filter service 依賴模塊。
resolve阻塞,保證對應視圖中的命令(controller,directive,filiter) 注入完成後再run
function config(templateUrl, controllerName, directives) { if (!$controllerProvider) { throw new Error("$controllerProvider is not set!"); } var defer, html, routeDefinition = {}; routeDefinition.templateUrl =templateUrl routeDefinition.controller = controllerName; routeDefinition.resolve = { delay:function ($q, $rootScope) { defer = $q.defer(); var dependencies = [controllerName]; if (directives) { dependencies = dependencies.concat(directives); } require(dependencies, function () { //按需加載 所需的控制器 directives 模塊 , // 經過$controllerProvider.register $compileProvider.directive建立 var controller = arguments[0], template = ""; for (var i = 2; i < arguments.length; i++) { lazyDirectives.register(arguments[i]); } $controllerProvider.register(controllerName, controller); /*建立控制器*/ html = template; defer.resolve(); /*加載完 返回resolve狀態*/ $rootScope.$apply() }) return defer.promise; } } return routeDefinition; }
$routeProvider.when('/view2', routeConfig.config('./partials/view2.html', 'controllers/second', ['directives/version']));