饥人谷技术博客

Requirejs初体验

2017-03-14  本文已影响59人  朱小维

作为刚刚入门前段的小白,前不久刚刚接触了js模块化的概念,从该开始写代码时的各种全局变量飞,到现在的封装模块,感觉又上了那么一个台阶了,不再那么业余了。接下来就总结一下最近的学习心得。

js模块化

  1. 没有模块化的时候
function f1(){}
function f2(){}

缺点:会污染全局变量

  1. 将变量封装在对象内
var obj1 = {
  f1:function (){},
  f2:function (){}
}

缺点:对象的属性直接暴露在外面,可以被随意修改,封装性不好

  1. 使用立即执行函数
var module1 = (function(){
  function f1(){}
  function f2(){}
  return {
    f1:f1,
    f2:f2
  }
})()
module1.f1()
module1.f2()

这样写的好处在于,使用者不能修改模块内部规定好的变量和函数。

  1. 模块化标准

js模块化主要有两种规范:CommonJS和AMD

  1. CommonJS应用于服务器端(nodejs环境下)
  2. AMD规范应用于浏览器端(浏览器环境)
  3. 注:CommonJS采用同步加载模块策略,服务器端js文件都放在硬盘上可以同步读取;AMD全称"asynchronous module definition",异步模块定义,浏览器请求js文件是异步的,这也是浏览器不能使用CommonJS加载模块的原因。

AMD规范举例

引用模块
require(["math"],function(math){
  math.add();
});
其中math模块的加载和math.add()方法调用不是同步的,而是等待math模块请求到之后才会调用math方法。

关于同步异步的知识可以参考阮一峰的js教程的单线程模式

RequireJS库

使用requirejs的原因

最早由于网页功能没有那么复杂,所有js代码都放在一个文件内,随着功能的不断增强,js代码需要分模块编写,于是分成不同的文件存放不同的模块。

<script src="1.js"></script>
<script src="2.js"></script>
<script src="3.js"></script>

上面写法的缺点:

  1. 依赖必须按照依赖顺序写,依赖性越强的js代码要放在下面,比如3.js依赖1.js的话,3.js就必须放在1.js下面,一旦文件多了,依赖关系复杂,就不太容易处理了;
  2. 分文件存放模块,会产生很多网络请求,网络请求越多网页失去响应的时间就会越长。

requirejs产生就是为了解决上述两个问题。

requirejs使用方法

  1. 网页中只有一个script标签,如下
    <script data-main="js/main.js" src="js/reqire.js"></script>
    data-main属性内存放js的入口文件;
    src属性存放require.js文件的路径。
  2. 主模块写法
//main.js
requirejs.config({
  baseUrl:"",
  paths:{
    
  }
});
require(["jquery","event"],function($,event){
});

包含两部分:配置和自定义代码。
配置:使用requirejs.config()方法,参数是一个对象。baseUrl属性可以指定一个默认地址,然后模块的地址就可以以这个默认地址作为参考系来设置了;paths属性可以再相对于baseUrl属性设置更多的绝对路径。这样做的目的是为了避免路径较深时,写很多长路径名。
例如:文件路径如下

如果不设置baseUrl,我们使用模块时,必须向下面这么用

require(["js/app/gotop",js/lib/jquery])

使用baseUrl+paths:

require.config({
    baseUrl:"js",
    paths{
      lib:"lib",
      app:"app"
    }
})
require(["app/gotop","lib/jquery"])

注:如果模块名符合下述三种条件之一则不使用baseUrl+paths的方式寻找模块,而是直接从加载require.js文件的html文件的所在目录开始寻找模块。

3.定义一个模块

//select.js
define(["lib/jquery"],function($){
  function sel(selecor){
     return $(selector)
  }
  return {
     sel:sel
  }
})

define定义了一个select模块,第一个参数是select模块所依赖的模块,第二个参数是回调函数,当jquery模块加载完成后,开始执行select模块的定义。

如果另一个模块需要使用select模块,需要按下面方法加载:

//main.js
require(["select"],function(select){
  var tab = select.sel(".tab");
})

4.r.js的使用

我们使用以上方法将一个一个模块按规范书写后,就不再需要考虑掉用他们的时候先引用谁后引用谁了,这个工作已经由requirejs帮我们完成了。但是这只解决了引用顺序的问题,仍然会产生很多的网络请求,这时候就轮到r.js登场了,它可以帮我们把之前定义好的模块都打包压缩到一个文件内。

安装requirejs:

npm install -g requirejs

以下面的例子为例:

<!DOCTYPE html>
<html>
    <head>
        <title>My App</title>
        <link rel="stylesheet" type="text/css" href="css/main.css">
        <script data-main="scripts/main.js" src="scripts/require.js"></script>
    </head>
    <body>
        <h1>My App</h1>
    </body>
</html>

main.js是入口文件,依赖于one,two,three。

//main.js
require.config({
 baseUrl:"scripts"
})

首先我们要在index.html所在路径新建一个build.js,用于存放r.js所需要的配置文件。

//build.js
({
 baseUrl:"script",//这个路径是相对于build.js文件所在路径的,不是index.html
 paths:{
      //也可以根据需要添加
 },
 name:"main",//入口文件
 out:"merge.js"//输出文件的路径及文件名称,路径不是相对于baseUrl的,而是相对于build.js所在路径的
})

新建好build.js后,在命令行切换至build.js所在目录,执行如下命令

r.js -o build.js

生成mergr.js后,我们还要修改html中script标签的data-main属性

<script data-main="merge.js" src="require.js"></script>

此时,整个html页面就只有一条两条html请求了,即merge.js和require.js。

上一篇下一篇

猜你喜欢

热点阅读