前端模块化工具 requireJs的使用;
虽然说现在主流的框架是webpack+vue/angular/react;但requireJs也曾是一段红红火火的历史;不懂require的我来复古一下;最近在做测试的时候把写好的网页丢到远程服务器上,发现了一个问题;
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8" /> <title>Document</title> <style type="text/css"> #dom{width:200px;height:200px;} </style> </head> <body> <div id="dom"></div> </body> </html> <script src="echart.min.js"></script> <script src="my.js"></script>
简单描述一下:
用了第三个方的echart库写了一个柱状图:
<script src="echart.min.js"></script> 仅仅是引用:
<script src="my.js"></script> 引入的是具体代码的实现:
一般看来觉得正常,但是在真实的网络环境中,浏览器报错:echarts is not defined; 当然知道是echarts出问题了;这明显是加载顺序出问题了;(再刷新一次正常了;说明浏览器会缓存一些文件;)
requireJs就是为这个而生的一个依赖加载工具: 下面是index部分内容;
在没有使用requireJs之前项目目录是:
------------------------------------------
-------------------------------------------
gongan.html中是这样的:引入的全是script标签:
-------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
下面使用requireJs. html变成这样了: src是require.js源文件的路径,require这个库可以去官网下载:http://requirejs.org/docs/download.html
data-main是入口文件,下面会详细说明的; async=true是异步的script属性,不阻塞网页加载 defer是兼容IE的写法;
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8" /> <title>公安主页</title> <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> <meta name=viewport content="width=device-width, initial-scale=1,user-scalable=no"> <link rel="stylesheet" type="text/css" href="style/css/index.css"> <link rel="stylesheet" type="text/css" href="style/fonts/fonts.css"> <script src="style/lib/require.js" data-main="style/js/main" async=true defer></script> </head> <body class="iframe-body"> <div id="index-g"> <div class="today-data"></div> <div class="im-working"></div> <div class="last-three-items clearfix"></div> <div class="index-footer-nav clearfix"></div> </div> </body> </html>
目录结构变成这样了(其实目录结构不一定要这样,路径对了就行了);
---------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
发现会多了一个util.js文件(文件位置随便放,路径对了就行;其实不用新建文件夹也可以,);其中的文件就是改写了原来inner-index.js文件;
先看看两者有什么变化,后面再解释(main.js配置后面见解释):
-------------------------------------------------
inner-index.js文件如下:(全部是通常写的函数式编程,最后在window.onload中调用了);
util.js文件如下:
-------------------------------------------------
下面开始具体讲配置,下面是 main.js的:
baseUrl:是配置一个基路径,什么是基路径? 就是以下模块, 如 jquery paths路径(在这里默认是.js后缀名)是 ../lib/juery-1.9.1.min , 那么真正的路径是两者的叠加;这里只是方便书写;
paths:说到这里应该很明白了;(其实你可以不用写baseUrl这个属性,在paths中把路径写全就可以了,一样的效果;);
paths对象中的全是模块,左边是模块名,右边的路径;
于是require.config()函数就配置完了,下面是require()使用;
例如:require(["util"],function(u){ });就是得到模块until要干嘛的,u这个参数其实就是代替了这个模块的引用;
那么你一定会问,util没有配置路径也可以使用? 其实路径是baseUrl+paths的组合路径,既然paths没有,那么使用的就是baseUrl的值,(而刚好util.js在这个文件夹中,其实是故意的);
u.ec_1(); 这个函数调用来自 util.js; util.js中实际是是定义模块(require中,无非就是require,define);
看看格式: define()函数有两个参数,第一个是一个数组,里面放的是依赖,就是依赖那个文件,即先加载那个文件在执行回调函数(第二个参数)的中的内容;
这就根本上解决了文章开头描述的那个问题;可以到浏览器 network查看 echarts文件确实是优先加载于 util.js;
回调函数的返回值是一个对象 ,我就是把原来 inner-index.js中的函数式编程中的各个函数的函数体放到返回值的函数中重写一遍而已;这是必须的,遵循AMD规范;
然后看require(["util"],function(){ //函数调用 });就是这么回事;
下一行:require["repond"],function(){ } Ie8响应媒体查询的一个js脚本,纯粹是引入进来而已;没事做,这个不必须的文件放在条件注释的scirpt标签职中更好;
---------------------------------------------------
-----------------------------------------------------------------------------------------------------
如何引入非标准的AMD库?
上面说的都是标准的AMD js的引入,包括自己定义的也好,也是定义标准AMD的;
比如某个作者 写了一个 aa.js文件,他偏偏是函数式编程;
文件内容如下:("假设这个模块取名 a1")
function aa(){
console.log(12345);
}
按照前面的方式:("假设路径已经配置好了");
require( ["a1"],function(aa){
aa(); //这肯定是行不通的;
});
正确方式是
require.config({
baseUrl://////,
paths://///
shim:{
a1:{exports:aa}
}
});
require(["a1"],function(aa){ aa() });
另外假如这个js问文件有多个函数呢,上这种方式又失效了;
正确配置是:
shim:{
init:function(){
return {
aa:aa,
bb:bb
}
}
};
使用 :require(["a1"],function(a1){ a1.aa();a1.bb() });