首先认识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']));