JS模块化开发(requireJS)

使用模块化开发的好处:

通过 exports 暴露接口。这意味着不需要命名空间了,更不需要全局变量。这是一种彻底的命名冲突解决方案。

通过 require 引入依赖。这可以让依赖内置,开发者只需关心当前模块的依赖,其他事情 Sea.js/ Require.js 都会自动处理好。对模块开发者来说,这是一种很好的 关注度分离,能让程序员更多地享受编码的乐趣

实现JS模块化开发,目前有两个规范,一个是AMD规范,一个是CMD规范。

RequireJS遵循的是AMD规范。AMD推崇依赖前置。

SeaJS遵循的CMD规范。CMD推崇依赖就近(按需加载)

AMD:API根据使用范围有区别,但使用同一个api接口

CMD:每个API的职责单一

AMD规范的模块风格

1、 定义模块用module变量,它有一个方法declare

2、 declare接受一个函数类型的参数,如称为factory

3、 factory有三个参数分别为require、exports、module,factory使用返回值和exports导出API. factory如果是对象类型,则将该对象作为模块输出

define(function(require, exports, module) {
    var base = require(‘base‘);
    exports.show = function() {
    // todo with modulebase
    }
});

使用require获取依赖模块,使用exports导出API。

除了require之外,AMD还保留了一个关键字require。require作为规范保留的全局标识符,可以实现为modile loader.

AMD的库有RequireJS、curl、Dojo、Nodules等

requireJS和seaJS应该是各有千秋,但是因为我之前的一个项目中使用到了requireJS,所以我选择对requireJS进行深入研究。

requireJs

(1)实现js文件的异步加载,避免网页失去响应;

(2)管理模块之间的依赖性,便于代码的编写和维护。

RequireJS用法介绍。

requirejs官网是: http://requirejs.org/

官方下载地址:http://requirejs.org/docs/release/2.1.20/minified/require.js

先下载require.js.

require.config是用来定义别名的,在paths属性下配置别名。然后通过requirejs(参数一,参数二);参数一是数组,传入我们需要引用的模块名,第二个参数是个回调函数,回调函数传入一个变量,代替刚才所引入的模块。

require.js的加载

1、在页面底部加载。

2、<script src="js/require.js" defer async="true" ></script>

async属性表面这个文件需要异步加载,避免网页失去响应,IE不支持async,需要使用defer属性。

加载require.js以后,下一步就要加载我们自己的代码了。

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

data-main属性的作用是,指定网页程序的主模块。

main.js文件

引入模块也可以只写require()。requirejs通过define()定义模块,定义的参数上同。在此模块内的方法和变量外部是无法访问的,只有通过return返回才行.

require的项目中,所有需要引入的文件都不要写.js的后缀名,因为requirejs会自动添加.js的后缀名。

define 模块

将该模块命名为math.js保存。

define 定义模块方法只能用在独立的js文件中,不能在页面中直接使用。

否则会报 Mismatched anonymous define() module 错误。

没有依赖

如果定义的模块不依赖其他模块,则可以:

AMD推荐的风格通过返回一个对象做为模块对象,CommonJS的风格通过对module.exports或exports的属性赋值来达到暴露模块对象的目的。

当写一个没有任何依赖的模块,并且只是返回一个对象包含一些功能函数

循环依赖

在一些情况中,我们可能需要模块moduleA和moduleA中的函数需要依赖一些应用。这就是循环依赖。

math.js引入模块方法

AMD规范定义的require()函数:

require([‘moduleA‘, ‘moduleB‘, ‘moduleC‘],
    function (moduleA, moduleB, moduleC){
    // some code here
  });

require()函数接受两个参数。第一个参数是一个数组,表示所依赖的模块,上例就是[‘moduleA’, ‘moduleB’, ‘moduleC’],即主模块依赖这三个模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。

require()异步加载moduleA,moduleB和moduleC,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。

假定主模块依赖jquery、underscore和backbone这三个模块,main.js就可以这样写:

require([‘jquery‘, ‘underscore‘, ‘backbone‘], function ($, _, Backbone){
    // some code here
  });

require.js会先加载jQuery、underscore和backbone,然后再运行回调函数。主模块的代码就写在回调函数中。

模块的加载

主模块的依赖模块是[‘jquery’, ‘underscore’, ‘backbone’]。默认情况下,require.js假定这三个模块与main.js在同一个目录,文件名分别为 jquery.js,underscore.js和backbone.js,然后自动加载。

使用require.config()方法,我们可以对模块的加载行为进行自定义。require.config()就写在主模块(main.js)的头部。参数就是一个对象,这个对象的paths属性指定各个模块的加载路径。

上面的代码给出了三个模块的文件名,路径默认与main.js在同一个目录(js子目录)。如果这些模块在其他目录,比如js/lib目录,则有两种写法。一种是逐一指定路径。

另一种则是直接改变基目录(baseUrl)。

如果某个模块在另一台主机上,也可以直接指定它的网址,比如:

require.js要求,每个模块是一个单独的js文件。这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度。因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数。

在代码中require一个文件多次,不会导致浏览器反复加载,即使反复require它,它也只加载一次。

CDN回退,当CDN加载不正确时,回退到本地相应的库2,通过require.config实现。

AMD模块的写法

require.js加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写。

具体来说,就是模块必须采用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。

//math.js

加载方法如下:

如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性。

当require()函数加载上面这个模块的时候,就会先加载myLib.js文件。

加载非规范的模块

理论上,require.js加载的模块,必须是按照AMD规范、用define()函数定义的模块。但是实际上,虽然已经有一部分流行的函数库(比如jQuery)符合AMD规范,更多的库并不符合.require.js能够加载非规范的模块,方法是,在用require()加载之前,要先用require.config()方法定义它们的一些特征。

举例来说,underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载它们的话,必须先定义它们的特征。

require.config()接受一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块。具体来说,每个模块要定义(1)exports值(输出的变量名),表明这个模块外部调用时的名称;(2)deps数组,表明该模块的依赖性。

得到模块的地址

var path = require.toUrl("./style.css");

JSONP

require.js插件

require.js还提供一系列插件,实现一些特定的功能。

domready插件,可以让回调函数在页面DOM结构加载完成后再运行。

text和image插件,则是允许require.js加载文本和图片文件

类似的插件还有json和mdown,用于加载json文件和markdown文件。

r.js压缩

Require.js 提供一个脚本 r.js ,可以将所有使用到的模块压缩成一个脚本文件,r.js 可以使用node.js 来执行。

在压缩模块前,需要写一个配置文件,说明主模块名,压缩后的文件名,哪些模块不要压缩

没有使用 define 定义的模块都不要压缩,包括 jquery,backbone 等库及其插件

时间: 2024-12-19 11:00:06

JS模块化开发(requireJS)的相关文章

JS模块化工具requirejs教程(一):初识requirejs

随着网站功能逐渐丰富,网页中的js也变得越来越复杂和臃肿,原有通过script标签来导入一个个的js文件这种方式已经不能满足现在互联网开发模式,我们需要团队协作.模块复用.单元测试等等一系列复杂的需求. RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的RequireJS压缩后只有14K,堪称非常轻量.它还同时可以和其他的框架协同工作,使用RequireJS必将使您的前端代码质量得以提升. requirejs能带来什么好处 官方对requ

【转】JS模块化工具requirejs教程(一):初识requirejs

随着网站功能逐渐丰富,网页中的js也变得越来越复杂和臃肿,原有通过script标签来导入一个个的js文件这种方式已经不能满足现在互联网开发模式,我们需要团队协作.模块复用.单元测试等等一系列复杂的需求. RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的RequireJS压缩后只有14K,堪称非常轻量.它还同时可以和其他的框架协同工作,使用RequireJS必将使您的前端代码质量得以提升. requirejs能带来什么好处 官方对requ

JS模块化开发:使用SeaJs高效构建页面

一.扯淡部分 很久很久以前,也就是刚开始接触前端的那会儿,脑袋里压根没有什么架构.重构.性能这些概念,天真地以为前端===好看的页面,甚至把js都划分到除了用来写一些美美的特效别无它用的阴暗角落里,就更别说会知道js还有面向对象,设计模式,MVC,MVVM,模块化,构建工具等等这些高大上的概念了.现在想想还真是Too young too naive.前两天某大神在群里分享他招聘前端的心得的时候就说,就是那些以为能写两个页面就可以自称前端的人拉低了行业水平.这样看来前两年我还真的扯了不少后腿呢……

JS模块化工具requirejs教程(二):基本知识

前一篇:JS模块化工具requirejs教程(一):初识requirejs我们以非常简单的方式引入了requirejs,这一篇将讲述一下requirejs中的一些基本知识,包括API使用方式等 基本API require会定义三个变量:define,require,requirejs,其中require === requirejs,一般使用require更简短 define 从名字就可以看出这个api是用来定义一个模块 require 加载依赖模块,并执行加载完后的回调函数 前一篇中的a.js:

JS模块化开发(三)——seaJs+grunt

1.seaJs直接构建存在的问题 由于模块之间的依赖require引用的是模块名,当多个js模块被合并成一个时,会由于找不到模块名而报错 2.seaJs+grunt开发 用到的插件:grunt-cmd-transport和grunt-cmd-concat       (CMD规范) grunt-cmd-transport:提取本模块的ID和本模块所依赖的ID(数组格式),作为define函数的两个参数:define(ID,[依赖数组],function(require,exports,modul

【转】JS模块化工具requirejs教程(二):基本知识

前一篇:JS模块化工具requirejs教程(一):初识requirejs 我们以非常简单的方式引入了requirejs,这一篇将讲述一下requirejs中的一些基本知识,包括API使用方式等. 基本API require会定义三个变量:define,require,requirejs,其中require === requirejs,一般使用require更简短 define 从名字就可以看出这个api是用来定义一个模块 require 加载依赖模块,并执行加载完后的回调函数 前一篇中的a.j

js模块化开发

为什么要进行模块化开发? 1.当你写了一个这样的comm.js文件时,里面有function tab(){}方法,这时,你给你的同事用,你同事把这个comm.js引入页面后,在页面上又写了一个function tab(){},这时,就会覆盖你在comm.js中的tab方法.因为这个同事不知道你comm.js中有tab这个方法名. 2.如果你同事在页面上引入了你写的comm.js后,又引入了一个第三方插件xxx,而这个xxx插件里面刚好也有tab方法,那这时就会出现问题.你同事就会找你,说你写的c

JS模块化开发----require.js

前言 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了,jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得前端开发得到重视,也使得前端项目越来越复杂,然而,JavaScript却没有为组织代码提供任何明显帮助,甚至没有类的概念,更不用说模块(module)了,所以,进行模块化开发的重要性就不言而喻了.那么什么是模块呢? 一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功

js模块化开发--AMD--CMD

什么是模块化开发? 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了,jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得前端开发得到重视,也使得前端项目越来越复杂,然而,JavaScript却没有为组织代码提供任何明显帮助,甚至没有类的概念,更不用说模块(module)了,那么什么是模块呢? 一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.模块开发