requirejs는 JavaScript 파일 및 모듈 로더입니다. requireJS를 사용하면 JavaScript 코드를 파일과 모듈로 분리하는 동시에 각 모듈 간의 종속성을 관리할 수 있습니다.
RequireJS의 목표는 코드의 모듈화를 장려하는 것이며 기존의 "script" 태그와는 다른 스크립트 로딩 단계를 사용합니다. RequireJS를 사용하여 모듈식 스크립트를 로드하면 코드의 로딩 속도와 품질이 향상됩니다.
1. require.js를 사용하는 이유는 무엇인가요?
초창기에는 모든 Javascript 코드가 하나의 파일에 작성되어 있었는데, 이 파일 하나만 로드하면 충분했습니다. 나중에는 코드가 점점 많아져서 하나의 파일로는 더 이상 부족해 여러 파일로 나누어 순차적으로 로드해야 했습니다. 많은 사람들이 다음 웹페이지 코드를 본 적이 있을 것입니다.
<script src="1.js"></script> <script src="2.js"></script> <script src="3.js"></script> <script src="4.js"></script> <script src="5.js"></script> <script src="6.js"></script>
이 코드는 여러 js 파일을 순차적으로 로드합니다.
이런 글쓰기 방식에는 큰 단점이 있습니다.
require.js는 다음 두 가지 문제를 해결하기 위해 탄생했습니다.
웹 페이지의 응답 손실을 방지하기 위해 js 파일의 비동기 로딩을 달성합니다.
모듈 간의 종속성 관리를 더 쉽게 만듭니다. 코드를 작성하고 유지 관리합니다.
2. require.js 로딩
require.js를 사용하기 위한 첫 번째 단계는 공식 홈페이지에서 최신 버전을 다운로드하는 것입니다.
다운로드 후 js 하위 디렉토리에 위치하여 로딩이 가능한 것으로 가정합니다.
7c439788e166f531c8ad0b30265c71032cacc6d41bbb37262a98f745aa00fbf0
어떤 사람들은 이 파일을 로드하면 웹페이지가 응답하지 않을 수도 있다고 생각할 수도 있습니다. 해결 방법은 두 가지가 있습니다.
하나는 웹 페이지 하단에 로드하는 것이고, 다른 하나는 다음과 같이 작성하는 것입니다.
54c41a54ac9dfbd45faf7460f9a4c6192cacc6d41bbb37262a98f745aa00fbf0
async 속성은 웹페이지가 응답하지 않는 것을 방지하기 위해 이 파일을 비동기적으로 로드해야 함을 나타냅니다. IE는 이 속성을 지원하지 않고 defer만 지원하므로 defer도 작성합니다.
require.js를 로드한 후 다음 단계는 자체 코드를 로드하는 것입니다. 우리 자신의 코드 파일이 main.js이고 js 디렉터리에도 있다고 가정합니다. 그런 다음 다음과 같이 작성하면 됩니다.
35be17e58c59207c30045b58673f385a2cacc6d41bbb37262a98f745aa00fbf0
함수 data-main 속성 중 웹 프로그램의 메인 모듈을 지정하는 것입니다.
위의 예에서는 js 디렉토리 아래의 main.js입니다. 이 파일은 require.js에 의해 먼저 로드됩니다. require.js의 기본 파일 확장자는 js이므로 main.js를 main으로 축약할 수 있습니다.
3. 메인 모듈 작성 방법
이전 섹션에서는 main.js를 "메인 모듈"이라고 부르는데, 이는 전체 웹 페이지의 진입 코드를 의미합니다. 이는 C 언어의 main() 함수와 약간 유사하며 모든 코드는 여기에서 실행되기 시작합니다.
main.js를 작성하는 방법을 살펴보겠습니다.
우리 코드가 다른 모듈에 의존하지 않는다면 자바스크립트 코드를 직접 작성할 수 있습니다.
require() 함수는 두 개의 매개변수를 받습니다. 첫 번째 매개변수: 의존하는 모듈을 나타내는 배열입니다. 위의 예는 ['moduleA', 'moduleB', 'moduleC']입니다. 즉, 메인 모듈은 이 세 가지 모듈에 의존합니다. 🎜>// main.js alert("加载成功!"); 但这样的话,就没必要使用require.js了。真正常见的情况是,主模块依赖于其他模块,这时就要使用AMD规范定义的的require()函数。 // main.js require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){ // some code here });이전에 지정한 모듈이 모두 성공적으로 로드되면 호출되는 콜백 함수입니다. 로드된 모듈은 이 함수에 매개변수로 전달되므로 이러한 모듈은 콜백 함수 내에서 사용할 수 있습니다. require()는 moduleA, moduleB 및 moduleC를 비동기식으로 로드하며 브라우저는 응답을 잃지 않습니다. 지정된 콜백 함수는 이전 모듈이 성공적으로 로드된 후에만 실행되어 종속성 문제를 해결합니다. 아래에서는 실제 사례를 살펴보겠습니다. 메인 모듈이 jquery, 밑줄 및 백본의 세 가지 모듈에 의존한다고 가정하면 main.js는 다음과 같이 작성할 수 있습니다.
require.js는 먼저 jQuery, 밑줄 및 백본을 로드합니다. 백본을 선택한 다음 콜백 함수를 다시 실행하세요. 콜백 함수에는 메인 모듈의 코드가 작성되어 있습니다.
4. 모듈 로딩
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){ // some code here });이전 섹션의 마지막 예에서 메인 모듈의 종속 모듈은 ['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 디렉토리와 같은 다른 디렉토리에 있는 경우 이를 작성하는 방법에는 두 가지가 있습니다.
하나는 경로를 하나씩 지정하는 것입니다.
require.config({ paths: { "jquery": "jquery.min", "underscore": "underscore.min", "backbone": "backbone.min" } });
다른 하나는 기본 디렉터리(baseUrl)를 직접 변경하는 것입니다.
모듈이 다른 호스트에 있는 경우 다음과 같이 해당 URL을 직접 지정할 수도 있습니다.require.config({ baseUrl: "js/lib", paths: {"jquery": "jquery.min", "underscore": "underscore.min", "backbone": "backbone.min"} });
require.config({ paths: { "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min" } });
require.js要求:
每个模块是一个单独的js文件。这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度。因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数。
五、AMD模块的写法
require.js加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写。
具体来说,就是模块必须采用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。
假定现在有一个math.js文件,它定义了一个math模块。那么,math.js就要这样写:
// math.js define(function (){ var add = function (x,y){ return x+y; }; return { add: add }; });
加载方法如下:
// main.js require(['math'], function (math){ alert(math.add(1,1)); });
如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性。
define(['myLib'], function(myLib){ function foo(){ myLib.doSomething(); } return { foo : foo }; });
当require()函数加载上面这个模块的时候,就会先加载myLib.js文件。
六、加载非规范的模块
理论上,require.js加载的模块,必须是按照AMD规范、用define()函数定义的模块。但是实际上,虽然已经有一部分流行的函数库(比如jQuery)符合AMD规范,更多的库并不符合。那么,require.js是否能够加载非规范的模块呢?
回答是可以的。
这样的模块在用require()加载之前,要先用require.config()方法,定义它们的一些特征。
举例来说,underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载它们的话,必须先定义它们的特征。
require.config({ shim: { 'underscore': { exports: '_' }, 'backbone': { deps: ['underscore', 'jquery'], exports: 'Backbone' } } });
require.config()接受一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块。具体来说,每个模块要定义(1)exports值(输出的变量名),表明这个模块外部调用时的名称;(2)deps数组,表明该模块的依赖性。
比如,jQuery的插件可以这样定义:
shim: { 'jquery.scroll': { deps: ['jquery'], exports: 'jQuery.fn.scroll' } }
七、require.js插件
require.js还提供一系列插件,实现一些特定的功能:
domready插件,可以让回调函数在页面DOM结构加载完成后再运行。
require(['domready!'], function (doc) { // called once the DOM is ready });
text和image插件,则是允许require.js加载文本和图片文件。
define([ 'text!review.txt', 'image!cat.jpg' ], function (review, cat) { console.log(review); document.body.appendChild(cat); } );
类似的插件还有json和mdown,用于加载json文件和markdown文件。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持PHP中文网!
更多浅析js的模块化编写 require.js相关文章请关注PHP中文网!