您的位置:首页 > 产品设计 > UI/UE

支持seaJs和requireJs的前端模块开发方案(二):业务页面和入口脚本init.js

2016-09-26 11:19 701 查看
前言

前一篇文章已经对方案的基本作用、目录要求已经做了说明,请务必先阅读

本文将对业务页面以及业务页面需要引入的唯一脚本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则为自动将模块间的引用进行合并。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息