Closed h2y closed 7 years ago
在我的 XSYU-GMS 项目中,我已经简单实现了一个这样的轮子,取名为 Nsert,用法大概是这样的:
$.nsert(['js-xlsx', 'chart-JS'], function(){
// code there
})
有时间会将其完善并发布。
这个库与 AMD 等加载器不同之处在于,AMD 要求被加载的代码通过 AMD 规范进行过 define,定义了一段代码暴露出的接口,以及依赖的其他模块。但是,并不是所有的第三方代码都进行了 AMD 声明。
Nsert 是一个通用的加载器,将任何的 JS 库按需加载到页面中。
向全局暴露两个方法:Nsert
和 Nsert_register
用于注册一个模块的相关信息
Nsert_register(String mod_name, Object mod_config);
mod_config 写法:
{
target: 'https://cdn.com/jq.min.js',
//必须。可以为链接也可以为相对地址
require: 'anthor_mod_name',
//可选。依赖的其他模块的名字,可以为字符串、数组或对象,分别代表依赖单个模块、按指定加载顺序依赖一组模块,以及不按加载顺序依赖一组模块
added: false,
//可选,默认为 false。标记这个模块是否已被添加至浏览器,这决定着 Nsert 会不会重复加载该模块
exports: ['$', 'jQuery'],
//可选。模块向顶层暴露的接口。如果定义了该设置,Nsert 会拦截这些接口,在调用的时候用参数的方式供用户使用
callback: function($, jQuery){},
//可选。加载完这个模块后调用的一个回调函数,可用来对工具库进行相关配置
kind: 'js'
//可选,默认为 'js'。模块类型,Nsert 在以后将会支持更多类型模块的加载
}
用于调用一个模块
Nsert(Mixed mod_name, Function? callback)
mod_name
需要调用的模块名,已通过 Nsert_register 注册。
可以为字符串、数组或对象,分别代表依赖单个模块、按指定加载顺序依赖一组模块,以及不按加载顺序依赖一组模块。
推荐在 Nsert_register 中对数组或对象再进行一次封装,为一个独立的模块后再使用 Nsert 单独调用。
callback
可选。调用完成后执行的代码。
如果调用的模块设定了 exports 属性,则将 exports 的对象依次作为参数传递给 callback。
mod_name 为数组或对象时,调用了多个模块,所以不会传递 exports 对应的参数!
使用 RequireJS + RequireCSS 可以达到目的。
没必要我重复造轮子了。
const bootcdn = 'https://cdn.bootcss.com/',
bower = '../../bower_components/';
require.config({
paths: {
jquery: bootcdn+"jquery/3.1.1/jquery.min",
bootstrap: bootcdn+'bootstrap/4.0.0-alpha.3/js/bootstrap.min'
},
shim: {
bootstrap: ['jquery', 'css!'+bootcdn+'bootstrap/4.0.0-alpha.3/css/bootstrap.min']
},
map: {
'*': {
'css': bower+'require-css/css.min'
}
}
});
seaJS 在内部采用正则替换,有一些隐坑。
而 Webpack 原生不支持 require 来自 http:// 的资源,不满足我的要求。
应用场景
在一个大型单页 Web App 中,不同的地方会使用一些特别的 JS 库来实现。比如,在点击应用中的 “导入 Excel” 按钮时,需要使用库
js-xlsx
来读取文件。按照常理,我们需要在
<head>
中加入这个 js 文件的<script>
标签,然而,在大型 Web App 中,“导入” 只是其中的一个功能,如果要把所有功能用到的所有依赖库都写到<head>
中,将非常的臃肿,大大影响首屏加载速度。目的
仅仅在需要的时候将需要的 js 库文件导入到浏览器运行环境中,自动处理依赖关系,也不会重复添加已添加过的依赖库。