支持seaJs和requireJs的前端模块开发方案(二):业务页面和入口脚本init.js
2016-09-26 11:19
701 查看
前言
前一篇文章已经对方案的基本作用、目录要求已经做了说明,请务必先阅读。
本文将对业务页面以及业务页面需要引入的唯一脚本init.js进行讲解,同时贴出全部代码,代码不做详细的讲解,有不懂的可以留言提问。
static_url变量为静态资源域,如不设置和设置为空,则自动为当前业务页面使用的域;
引入init.js文件的代码中设置了一个id和4个data标签,分别作用为:
id="ENTRY" 入口脚本的标识,不可变,用于识别当前页面是否使用自动模式;
data-type="amd" 加载器模式,可选amd或者cmd,分别代码了requireJs和seaJs;
data-app="amd-requireJs-demo" 当前页面所属的app名,或者app下的某个系统单元(当把方案作为某一个app时);
data-module="" 当前页面所属app的系统单元,设置为空时代表没有细分系统单元;
data-page="login" 当前面的业务脚本名,省略".js"后缀;
调试查看的效果为:
接下来就是实现异步串行加载所需JS文件,代码如下:
以上代码根据页面设置的钩子信息和window.ENTRY_CONF配置,异步串行加载了页面所需的脚本。在使用seaJs作为加载器时,有一个combo配置,开通的话会自动书写合并形式如“http://localhost:8861/static//??libs/cmd/seajs/seajs/2.1.1/sea.js,alias.js,apps/app2/js/config.js,apps/app2/js/login.js”;但是用requireJs作为加载器时无法自动进行合并,因为require.js配套的r.js辅件需要node环境,但是seaJs配套的combo.js则为自动将模块间的引用进行合并。
前一篇文章已经对方案的基本作用、目录要求已经做了说明,请务必先阅读。
本文将对业务页面以及业务页面需要引入的唯一脚本init.js进行讲解,同时贴出全部代码,代码不做详细的讲解,有不懂的可以留言提问。
一.业务页面
业务页面即入口页面有两种模式,一种为自动模式,该模式根据钩子调用init.js脚本,实现异步串行加载业务页面所需的所有脚本文件;一种为手动模式,手动模式即手动引入页面所需的所有脚本文件,业务脚本代码可放在页面中。自动模式:
<script type="text/javascript"> /*var static_url = 'http://localhost:8862';*/ </script> <script id="ENTRY" data-type="amd" data-app="amd-requireJs-demo" data-module="" data-page="login" src="http://localhost:8861/static/init.js"></script>
static_url变量为静态资源域,如不设置和设置为空,则自动为当前业务页面使用的域;
引入init.js文件的代码中设置了一个id和4个data标签,分别作用为:
id="ENTRY" 入口脚本的标识,不可变,用于识别当前页面是否使用自动模式;
data-type="amd" 加载器模式,可选amd或者cmd,分别代码了requireJs和seaJs;
data-app="amd-requireJs-demo" 当前页面所属的app名,或者app下的某个系统单元(当把方案作为某一个app时);
data-module="" 当前页面所属app的系统单元,设置为空时代表没有细分系统单元;
data-page="login" 当前面的业务脚本名,省略".js"后缀;
调试查看的效果为:
手动模式:
<script src="http://localhost:8861/static/libs/amd/require/2.2.0/require.min.js"></script> <script src="http://localhost:8861/static/alias.js"></script> <script src="http://localhost:8861/static/apps/amd-requireJs-demo/js/config.js"></script> <script type="text/javascript"> require(['jquery','global'], function ($,gloabl) { console.log('非自动'); var val = $('input[name="seller_name"]').val(); $('input[name="seller_name"]').val(val+'--'); console.log("login.js--->我是入口脚本,成功获取到了本页的标题:"+document.title); }); </script>手动模式就不过多讲解,和常规写法一致。
二.入口脚本init.js
脚本主要对实现2个功能:抛出自动模式下的全局变量、实现异步串行加载所需JS文件。window.ENTRY_CONF = window.ENTRY_CONF || { // web域,自动获取当前域 SITE_URL: document.location.protocol + "//" + location.hostname + (location.port ? ":" + location.port : "") + "/", // 页面运行开始时间 STIME: new Date().getTime(), //识别节点 NODE: document.getElementById("ENTRY"), // 是否自动加载JS AUTO_LOAD_SCRIPTS: function() { return this.NODE !== null ? true : false; }, // 提取架构方式 TYPE: function() { var tp = this.NODE.getAttribute("data-type"); if (tp === 'cmd' || tp === 'CMD') return 'cmd'; else if (tp === 'amd' || tp === 'AMD') return 'amd'; }, // 当前所属应用标识 APP: function() { var app = this.NODE.getAttribute("data-app") return app === '' || app === null ? '' : "apps/" + app + '/'; }, // 当前所属应用下的系统模块 MODULE: function() { var mod = this.NODE.getAttribute("data-module") return mod === '' || mod === null ? 'js/' : mod + '/js/'; }, // 当前所属应用下的系统模块 PAGE: function() { var page = this.NODE.getAttribute("data-page") return page === '' || page === null ? '' : '/' + page; }, // static资源域,优先获取页面定义的static_url SITE_STATIC_URL: function() { return 'undefined' === typeof static_url || '' === static_url ? this.SITE_URL : static_url + "/"; }, // 静态资源目录,当SITE_STATIC_URL为web域时使用 STATIC_FOLDER: function() { return this.SITE_STATIC_URL() === this.SITE_URL ? this.SITE_STATIC_URL() + 'static/' : this.SITE_STATIC_URL(); }, // 第三方资源目录细化路径 LIBS_FOLDER LIBS_FOLDER: function() { if (this.TYPE() === 'cmd') return this.STATIC_FOLDER() + 'libs/'; else if (this.TYPE() === 'amd') return this.STATIC_FOLDER() + 'libs/'; }, // 自有资产目录细化路径 ASSETS_FOLDER: function() { return this.STATIC_FOLDER() + 'assets/js/'; }, // 是否合并资源 COMBO: false }; //资源路径(全局) var _LIBSURL = ENTRY_CONF.LIBS_FOLDER()+ENTRY_CONF.TYPE()+'/'; var _ASSETSURL = ENTRY_CONF.ASSETS_FOLDER()+ENTRY_CONF.TYPE()+'/'; var _SYSTEMURL = ENTRY_CONF.STATIC_FOLDER() + ENTRY_CONF.APP() + ENTRY_CONF.MODULE();上面代码中定义了一些全局变量,并且抛出了3个资源路径变量分别为:_LIBSURL、_ASSETSURL、_SYSTEMURL,这3个变量代表了第三方公共资源目录、私有公共资源目录、app系统或系统下模块的资源目录。
接下来就是实现异步串行加载所需JS文件,代码如下:
// 入口 var entry = function() { if (!ENTRY_CONF.AUTO_LOAD_SCRIPTS()) { return false; } this.stime = ENTRY_CONF.STIME; this.staticFolder = ENTRY_CONF.STATIC_FOLDER(); this.labsFolder = ENTRY_CONF.LIBS_FOLDER(); this.combo = ENTRY_CONF.COMBO; this.type = ENTRY_CONF.TYPE(); this.app = ENTRY_CONF.APP(); this.module = ENTRY_CONF.MODULE(); this.page = ENTRY_CONF.PAGE(); this.init(); }; entry.prototype.init = function() { var self = this; var scripts = self.getScripts(); self.seriesLoadScripts(scripts, function() { return self.callback(); }); }; entry.prototype.getScripts = function() { var self = this, loaderJs, comboJs, loaderAliasJs, loaderConfigJs, pageJs; //加载器脚本 及 合并辅件 if (self.combo) { if (self.type === 'cmd' || self.type === 'CMD') { publicUrl = self.staticFolder + "/??", loaderJs = publicUrl + "libs/cmd/seajs/seajs/2.1.1/sea.js"; //加载器脚本 comboJs = ",libs/cmd/seajs/seajs-combo/1.0.1/seajs-combo.js"; //加载器脚本 loaderAliasJs = ",alias.js"; //总配置脚本 loaderConfigJs = "," + self.app + self.module + 'config.js'; //模块配置脚本 pageJs = "," + self.app + self.module + self.page + '.js'; //业务脚本 return [loaderJs + comboJs + loaderAliasJs + loaderConfigJs + pageJs]; //返回arr //demo->http://localhost:8861/static//??libs/cmd/seajs/seajs/2.1.1/sea.js,alias.js,apps/app2/js/config.js,apps/app2/js/login.js } else { console.log("requireJs无法自动合并模块路径,请关闭combo或改用cmd模式") return false; } } else { //加载器脚本 if (self.type === 'cmd' || self.type === 'CMD') loaderJs = self.labsFolder + "cmd/seajs/seajs/2.1.1/sea.js"; else if (self.type === 'amd' || self.type === 'AMD') loaderJs = self.labsFolder + "amd/require/2.2.0/require.min.js"; loaderAliasJs = self.staticFolder + "alias.js"; //总配置脚本 loaderConfigJs = self.staticFolder + self.app + self.module + 'config.js'; //模块配置脚本 pageJs = self.staticFolder + self.app + self.module + self.page + '.js'; //业务脚本 return [loaderJs, loaderAliasJs, loaderConfigJs, pageJs]; //返回arr } }; entry.prototype.seriesLoadScripts = function(scripts, callback) { if (typeof(scripts) != "object") var scripts = [scripts]; var s = new Array(), last = scripts.length - 1, recursiveLoad = function(i) { s[i] = document.createElement("script"); s[i].setAttribute("src", scripts[i]); s[i].onload = s[i].onreadystatechange = function() { if (! /* @cc_on!@ */ 0 || this.readyState == "loaded" || this.readyState == "complete") { this.onload = this.onreadystatechange = null; if (i !== last) recursiveLoad(i + 1); else if (typeof(callback) === "function") callback(); } } document.body.appendChild(s[i]); }; recursiveLoad(0); }; entry.prototype.callback = function() {}; //启用 new entry();
以上代码根据页面设置的钩子信息和window.ENTRY_CONF配置,异步串行加载了页面所需的脚本。在使用seaJs作为加载器时,有一个combo配置,开通的话会自动书写合并形式如“http://localhost:8861/static//??libs/cmd/seajs/seajs/2.1.1/sea.js,alias.js,apps/app2/js/config.js,apps/app2/js/login.js”;但是用requireJs作为加载器时无法自动进行合并,因为require.js配套的r.js辅件需要node环境,但是seaJs配套的combo.js则为自动将模块间的引用进行合并。
相关文章推荐
- Seajs 简易文档 提供简单、极致的模块化开发体验
- JavaScript的RequireJS库入门指南
- 深入探寻seajs的模块化与加载方式
- javascript模块化简单解析
- requireJS使用指南
- seajs中模块的解析规则详解和模块使用总结
- SeaJS入门教程系列之使用SeaJS(二)
- LABjs、RequireJS、SeaJS的区别
- 一篇文章掌握RequireJS常用知识
- RequireJS多页面应用实例分析
- 使用RequireJS优化JavaScript引用代码的方法
- 在JavaScript应用中使用RequireJS来实现延迟加载
- 在Html中使用Requirejs进行模块化开发实例详解
- 使用RequireJS库加载JavaScript模块的实例教程
- 基于RequireJS和JQuery的模块化编程――常见问题全面解析
- 基于RequireJS和JQuery的模块化编程日常问题解析
- 优化RequireJS项目的相关技巧总结
- seajs加载jquery时提示$ is not a function该怎么解决
- 小心!AngularJS结合RequireJS做文件合并压缩的那些坑
- require.js