JS(CommonJS, AMD, CMD)의 모듈 사양에 대한 자세한 설명

php是最好的语言
풀어 주다: 2018-08-07 09:21:44
원래의
1904명이 탐색했습니다.

먼저 대답해 주세요: 모듈이 왜 중요한가요?

답변: 모듈 덕분에 우리는 다른 사람의 코드를 더 편리하게 사용할 수 있고, 우리가 원하는 기능에 대해 우리가 원하는 모듈을 로드할 수 있습니다.
하지만 여기에는 전제가 있습니다. 즉, 모든 사람이 같은 방식으로 모듈을 작성해야 한다는 것입니다. 그렇지 않으면 당신은 당신의 글쓰기 방식이 있고 나는 내 글쓰기 방식이 있으면 엉망이 되지 않을까요!

그래서 다음 세 가지 모듈이 표준화되었고, 이 글도 게재되었습니다({얼굴 가리고 웃는다}라고 표기).

JS 모듈 사양(CommonJS, AMD, CMD), js 모듈화에 대해 들어본 적이 있다면 CommonJS나 AMD, 심지어 CMD에 대해서도 들어봤을 것입니다. 방금 들었어. 이제 이러한 사양이 무엇인지, 어떤 역할을 하는지 살펴보겠습니다. 이 기사에는 이 세 가지 사양의 소스와 해당 제품의 원리가 포함되어 있습니다.

1. CommonJS

1. 처음에는 JS가 공식적으로 정의된 API는 브라우저 기반 애플리케이션만 구축할 수 있다고 생각했습니다. CommonJS는 너무 편협하고(고급 단어인 돌팔이를 사용함) CommonJS API는 일반 애플리케이션(주로 브라우저가 아닌 애플리케이션)에서 사용하는 많은 API를 정의하여 이러한 격차를 메워줍니다. 궁극적인 목표는 Python, Ruby 및 Java와 유사한 표준 라이브러리를 제공하는 것입니다. 이 경우 개발자는 CommonJS API를 사용하여 애플리케이션을 작성할 수 있으며, 이러한 애플리케이션은 다양한 JavaScript 인터프리터 및 다양한 호스트 환경에서 실행될 수 있습니다.

CommonJS와 호환되는 시스템에서는 JavaScript를 사용하여 다음 프로그램을 개발할 수 있습니다:

(1). 서버 측 JavaScript 애플리케이션

(2). 그래픽 인터페이스 애플리케이션
(4). 하이브리드 애플리케이션(예: Titanium 또는 Adobe AIR)

2009년 미국 프로그래머 Ryan Dahl은 서버 측 프로그래밍에 JavaScript 언어를 사용하기 위해 node.js 프로젝트를 만들었습니다. 이는 "Javascript 모듈러 프로그래밍"의 공식적인 탄생을 의미합니다. 솔직히 말해서 브라우저 환경에서는 모듈이 없어도 큰 문제가 되지 않습니다. 결국 웹 프로그램의 복잡성은 제한적이지만 서버 측에서는 운영 체제 및 기타 응용 프로그램과 상호 작용할 수 있는 모듈이 있어야 합니다. 그렇지 않으면 프로그래밍 방법이 없습니다. NodeJS는 CommonJS 스펙을 구현한 것이며, webpack도 CommonJS 형태로 작성되었습니다.

node.js의 모듈 시스템은 CommonJS 사양을 참조하여 구현되었습니다. CommonJS에는 모듈을 로드하는 데 사용되는 전역 메서드 require()가 있습니다. 수학 모듈 math.js가 있다고 가정하면 다음과 같이 로드할 수 있습니다.

var math = require('math');

그런 다음 모듈에서 제공하는 메서드를 호출할 수 있습니다:

 var math = require('math');

Math .add(2,3); // 5

CommonJS에서 정의한 모듈은 다음과 같이 나뉩니다. {모듈 참조(필수)} {모듈 정의(내보내기)} {모듈 식별(모듈)}

require( )는 외부 모듈을 소개하는 데 사용됩니다. 내보내기 개체는 현재 모듈의 메서드나 변수를 내보내는 데 사용됩니다. 유일한 내보내기 포트는 모듈 자체를 나타냅니다.

Node는 CommonJS의 사양을 따르지만 몇 가지 절충안을 만들고 몇 가지 새로운 사항을 추가했습니다.

하지만 CommonJS에 대해 이야기하고 Node에 대해서도 이야기한 후에 NPM을 먼저 이해해야 한다고 생각합니다. NPM은 Node의 패키지 관리자로서 Node가 종속 패키지의 설치 문제를 해결하도록 돕는 것이 아니라 CommonJS 사양(또는 이론)을 따라야 합니다. CommonJS WIKI는 그 역사에 대해 이야기하고, 모듈, 패키지 등을 소개합니다.

commonJS의 원리와 간단한 구현에 대해 이야기해 보겠습니다.

1. 원리

브라우저가 CommonJS와 호환되지 않는 근본적인 이유는 4개의 Node.js 환경 변수가 부족하기 때문입니다.

  • module

  • exports

  • require

  • global

이 네 가지 변수를 제공할 수 있는 한 브라우저는 CommonJS 모듈을 로드할 수 있습니다.

다음은 간단한 예입니다.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><br><span class="token keyword">var module <span class="token operator">= <span class="token punctuation">{<br> exports<span class="token punctuation">: <span class="token punctuation">{<span class="token punctuation">}<br><span class="token punctuation">}<span class="token punctuation">;<br><br><span class="token punctuation">(<span class="token keyword">function<span class="token punctuation">(module<span class="token punctuation">, exports<span class="token punctuation">) <span class="token punctuation">{<br> exports<span class="token punctuation">.multiply <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(n<span class="token punctuation">) <span class="token punctuation">{ <span class="token keyword">return n <span class="token operator">* <span class="token number">1000 <span class="token punctuation">}<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">(module<span class="token punctuation">, module<span class="token punctuation">.exports<span class="token punctuation">)<span class="token punctuation">)<br><br><span class="token keyword">var f <span class="token operator">= module<span class="token punctuation">.exports<span class="token punctuation">.multiply<span class="token punctuation">;<br><span class="token function">f<span class="token punctuation">(<span class="token number">5<span class="token punctuation">)<span class="token comment"> // 5000 <br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
로그인 후 복사

위의 코드는 즉시 실행 함수에 두 개의 외부 변수인 module과 내보내기를 제공하고, 모듈은 이 즉시 실행 함수에 배치됩니다. 모듈의 출력 값은 module.exports에 배치되어 모듈 로딩을 구현합니다.

2. Browserify 구현

원리를 알면 도구를 만들 수 있습니다. Browserify는 현재 가장 일반적으로 사용되는 CommonJS 형식 변환 도구입니다.

main.js 모듈이 foo.js 모듈을 로드하는 예를 참조하세요.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><span class="token comment"><br>// foo.js<br>module<span class="token punctuation">.exports <span class="token operator">= <span class="token keyword">function<span class="token punctuation">(x<span class="token punctuation">) <span class="token punctuation">{<br> console<span class="token punctuation">.<span class="token function">log<span class="token punctuation">(x<span class="token punctuation">)<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><span class="token comment"><br>// main.js<br><span class="token keyword">var foo <span class="token operator">= <span class="token function">require<span class="token punctuation">(<span class="token string">"./foo"<span class="token punctuation">)<span class="token punctuation">;<br><span class="token function">foo<span class="token punctuation">(<span class="token string">"Hi"<span class="token punctuation">)<span class="token punctuation">;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
로그인 후 복사

main.js를 브라우저에서 사용할 수 있는 형식으로 변환하려면 다음 명령을 사용하세요.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ browserify main<span class="token punctuation">.js <span class="token operator">> compiled<span class="token punctuation">.js<br/></span></span></span></code></span>
로그인 후 복사

Browserify의 기능은 정확히 무엇인가요? browser-unpack을 설치하시면 선명하게 보실 수 있습니다.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ npm install browser<span class="token operator">-unpack <span class="token operator">-g<br/></span></span></code></span>
로그인 후 복사

그런 다음 앞서 생성한 compile.js의 압축을 풀어주세요.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ browser<span class="token operator">-unpack <span class="token operator">< compiled<span class="token punctuation">.js<br/><br/><span class="token punctuation">[<br/><span class="token punctuation">{<br/><span class="token string">"id"<span class="token punctuation">:<span class="token number">1<span class="token punctuation">,<br/><span class="token string">"source"<span class="token punctuation">:<span class="token string">"module.exports = function(x) {\n console.log(x);\n};"<span class="token punctuation">,<br/><span class="token string">"deps"<span class="token punctuation">:<span class="token punctuation">{<span class="token punctuation">}<br/><span class="token punctuation">}<span class="token punctuation">,<br/><span class="token punctuation">{<br/><span class="token string">"id"<span class="token punctuation">:<span class="token number">2<span class="token punctuation">,<br/><span class="token string">"source"<span class="token punctuation">:<span class="token string">"var foo = require(\"./foo\");\nfoo(\"Hi\");"<span class="token punctuation">,<br/><span class="token string">"deps"<span class="token punctuation">:<span class="token punctuation">{<span class="token string">"./foo"<span class="token punctuation">:<span class="token number">1<span class="token punctuation">}<span class="token punctuation">,<br/><span class="token string">"entry"<span class="token punctuation">:<span class="token boolean">true<br/><span class="token punctuation">}<br/><span class="token punctuation">]<br/></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span>
로그인 후 복사

보시다시피 browerify는 모든 모듈을 배열에 넣습니다. id 속성은 모듈 번호이고, source 속성은 모듈의 소스 코드이며, deps 속성은 모듈의 종속성입니다. 기준 치수.

foo.js가 main.js에 로드되기 때문에 deps 속성은 ./foo가 모듈 번호 1에 해당함을 지정합니다. 실행 중 브라우저는 require('./foo') 문을 만나면 자동으로 1번 모듈의 source 속성을 실행하고 실행된 module.exports 속성 값을 출력합니다.

3. Tiny Browser Require

Browserify는 매우 강력하지만 브라우저에서 작동할 수 없어 때로는 매우 불편합니다.

모카 내부 구현을 기반으로 순수 브라우저 CommonJS 모듈 로더tiny-browser-require를 만들었습니다. 명령줄이 전혀 필요하지 않고 브라우저에 직접 입력하면 됩니다. 전체 코드는 30줄이 넘습니다.

논리는 매우 간단합니다. 즉, 모듈을 배열로 읽어들이고 로딩 경로는 모듈의 ID입니다.

<code class="language-javascript"><span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-javascript"><br/><span class="token keyword">function <span class="token function">require<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">{<br/><span class="token keyword">var path <span class="token operator">= require<span class="token punctuation">.<span class="token function">resolve<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">var mod <span class="token operator">= require<span class="token punctuation">.modules<span class="token punctuation">[path<span class="token punctuation">]<span class="token punctuation">;<br/><span class="token keyword">if <span class="token punctuation">(<span class="token operator">!mod<span class="token punctuation">) <span class="token keyword">throw <span class="token keyword">new <span class="token class-name">Error<span class="token punctuation">(<span class="token string">&#39;failed to require "&#39; <span class="token operator">+ p <span class="token operator">+ <span class="token string">&#39;"&#39;<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">if <span class="token punctuation">(<span class="token operator">!mod<span class="token punctuation">.exports<span class="token punctuation">) <span class="token punctuation">{<br/> mod<span class="token punctuation">.exports <span class="token operator">= <span class="token punctuation">{<span class="token punctuation">}<span class="token punctuation">;<br/> mod<span class="token punctuation">.<span class="token function">call<span class="token punctuation">(mod<span class="token punctuation">.exports<span class="token punctuation">, mod<span class="token punctuation">, mod<span class="token punctuation">.exports<span class="token punctuation">, require<span class="token punctuation">.<span class="token function">relative<span class="token punctuation">(path<span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token punctuation">}<br/><span class="token keyword">return mod<span class="token punctuation">.exports<span class="token punctuation">;<br/><span class="token punctuation">}<br/><br/>require<span class="token punctuation">.modules <span class="token operator">= <span class="token punctuation">{<span class="token punctuation">}<span class="token punctuation">;<br/><br/>require<span class="token punctuation">.resolve <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(path<span class="token punctuation">)<span class="token punctuation">{<br/><span class="token keyword">var orig <span class="token operator">= path<span class="token punctuation">;<br/><span class="token keyword">var reg <span class="token operator">= path <span class="token operator">+ <span class="token string">&#39;.js&#39;<span class="token punctuation">;<br/><span class="token keyword">var index <span class="token operator">= path <span class="token operator">+ <span class="token string">&#39;/index.js&#39;<span class="token punctuation">;<br/><span class="token keyword">return require<span class="token punctuation">.modules<span class="token punctuation">[reg<span class="token punctuation">] <span class="token operator">&& reg<br/><span class="token operator">|| require<span class="token punctuation">.modules<span class="token punctuation">[index<span class="token punctuation">] <span class="token operator">&& index<br/><span class="token operator">|| orig<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/><br/>require<span class="token punctuation">.register <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(path<span class="token punctuation">, fn<span class="token punctuation">)<span class="token punctuation">{<br/> require<span class="token punctuation">.modules<span class="token punctuation">[path<span class="token punctuation">] <span class="token operator">= fn<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/><br/>require<span class="token punctuation">.relative <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(parent<span class="token punctuation">) <span class="token punctuation">{<br/><span class="token keyword">return <span class="token keyword">function<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">{<br/><span class="token keyword">if <span class="token punctuation">(<span class="token string">&#39;.&#39; <span class="token operator">!<span class="token operator">= p<span class="token punctuation">.<span class="token function">charAt<span class="token punctuation">(<span class="token number">0<span class="token punctuation">)<span class="token punctuation">) <span class="token keyword">return <span class="token function">require<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">var path <span class="token operator">= parent<span class="token punctuation">.<span class="token function">split<span class="token punctuation">(<span class="token string">&#39;/&#39;<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">var segs <span class="token operator">= p<span class="token punctuation">.<span class="token function">split<span class="token punctuation">(<span class="token string">&#39;/&#39;<span class="token punctuation">)<span class="token punctuation">;<br/> path<span class="token punctuation">.<span class="token function">pop<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;<br/><br/><span class="token keyword">for <span class="token punctuation">(<span class="token keyword">var i <span class="token operator">= <span class="token number">0<span class="token punctuation">; i <span class="token operator">< segs<span class="token punctuation">.length<span class="token punctuation">; i<span class="token operator">++<span class="token punctuation">) <span class="token punctuation">{<br/><span class="token keyword">var seg <span class="token operator">= segs<span class="token punctuation">[i<span class="token punctuation">]<span class="token punctuation">;<br/><span class="token keyword">if <span class="token punctuation">(<span class="token string">&#39;..&#39; <span class="token operator">== seg<span class="token punctuation">) path<span class="token punctuation">.<span class="token function">pop<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token keyword">else <span class="token keyword">if <span class="token punctuation">(<span class="token string">&#39;.&#39; <span class="token operator">!<span class="token operator">= seg<span class="token punctuation">) path<span class="token punctuation">.<span class="token function">push<span class="token punctuation">(seg<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token punctuation">}<br/><br/><span class="token keyword">return <span class="token function">require<span class="token punctuation">(path<span class="token punctuation">.<span class="token function">join<span class="token punctuation">(<span class="token string">&#39;/&#39;<span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
로그인 후 복사

使用的时候,先将上面的代码放入页面。然后,将模块放在如下的立即执行函数里面,就可以调用了。

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-html"><br/><script src="require.js" /><br/><br/><script><br/>require.register("moduleId", function(module, exports, require){<br/> // Module code goes here<br/>});<br/>var result = require("moduleId");<br/></script><br/></code></span>
로그인 후 복사

还是以前面的 main.js 加载 foo.js 为例。

<code class="language-javascript"><span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-javascript"><br/>require<span class="token punctuation">.<span class="token function">register<span class="token punctuation">(<span class="token string">"./foo.js"<span class="token punctuation">, <span class="token keyword">function<span class="token punctuation">(module<span class="token punctuation">, exports<span class="token punctuation">, require<span class="token punctuation">)<span class="token punctuation">{<br/> module<span class="token punctuation">.exports <span class="token operator">= <span class="token keyword">function<span class="token punctuation">(x<span class="token punctuation">) <span class="token punctuation">{<br/> console<span class="token punctuation">.<span class="token function">log<span class="token punctuation">(x<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">;<br/><span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;<br/><br/><span class="token keyword">var foo <span class="token operator">= <span class="token function">require<span class="token punctuation">(<span class="token string">"./foo.js"<span class="token punctuation">)<span class="token punctuation">;<br/><span class="token function">foo<span class="token punctuation">(<span class="token string">"Hi"<span class="token punctuation">)<span class="token punctuation">;<br/></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>
로그인 후 복사

注意,这个库只模拟了 require 、module 、exports 三个变量,如果模块还用到了 global 或者其他 Node 专有变量(比如 process),就通过立即执行函数提供即可。

二、AMD

基于commonJS规范的nodeJS出来以后,服务端的模块概念已经形成很自然地,大家就想要客户端模块。而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行。但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器环境。还是上面的代码,如果在浏览器中运行,会有一个很大的问题,你能看出来吗?

  var math = require('math');

  math.add(2, 3);

第二行math.add(2, 3),在第一行require('math')之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。您会注意到 require 是同步的。

这对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状态。

因此,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD规范诞生的背景。

CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,AMD(异步模块定义)出现了,它就主要为前端JS的表现制定规范。

AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:

  require([module], callback);

第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。如果将前面的代码改写成AMD形式,就是下面这样:

  require(['math'], function (math) {

    math.add(2, 3);

  });

math.add() 및 수학 모듈 로딩이 동기화되지 않아 브라우저가 정지되지 않습니다. 따라서 분명히 AMD는 브라우저 환경에 더 적합합니다. 현재 AMD 사양을 구현하는 두 가지 주요 Javascript 라이브러리는 require.js와curl.js입니다.

RequireJS는 AMD 사양을 구현합니다.

상세 요약: 다음은 RequireJS를 예로 들어 AMD 사양을 설명합니다

1. require.js를 사용하는 이유는 무엇입니까?

초창기에는 모든 Javascript 코드가 하나의 파일에 작성되어 있었는데, 이 파일 하나만 로드해도 충분했습니다. 나중에는 코드가 점점 많아져서 하나의 파일로는 더 이상 부족해 여러 파일로 나누어 순차적으로 로드해야 했습니다. 많은 분들이 다음 웹페이지 코드를 보셨으리라 믿습니다

 
 
  
  < ; script src="5.js">
 

이 코드는 여러 js를 순차적으로 로드합니다. 문서.

이런 글쓰기 방식에는 큰 단점이 있습니다. 우선, 로드할 때 브라우저는 웹 페이지 렌더링을 중지합니다. 더 많은 파일이 로드될수록 웹 페이지의 응답이 길어집니다. 둘째, js 파일 간의 종속성으로 인해 로드 순서가 엄격하게 보장되어야 합니다. 위의 예처럼) 1.js가 2.js 앞에 와야 하며, 의존성이 가장 큰 모듈을 마지막에 로드해야 합니다. 의존성이 복잡하면 코드 작성 및 유지 관리가 어려워집니다.

require.js는 다음 두 가지 문제를 해결하기 위해 탄생했습니다.

(1) 웹페이지가 응답하지 않는 것을 방지하기 위해 js 파일의 비동기 로딩을 구현합니다. 2) 코드 작성 및 유지 관리를 용이하게 하기 위해 모듈 간의 종속성을 관리합니다.

2. require.js 로드

require.js를 사용하는 첫 번째 단계는 공식 웹사이트에 접속하여 최신 버전을 다운로드하는 것입니다.

다운로드 후 js 하위 디렉토리에 넣어서 로딩이 가능한 것으로 가정합니다.

 

어떤 사람들은 이 파일을 로드하면 웹페이지가 응답하지 않을 수도 있다고 생각할 수도 있습니다. 두 가지 해결책이 있습니다. 하나는 웹 페이지 하단에 로드하는 것이고, 다른 하나는 다음과 같이 작성하는 것입니다.

 

async 속성은 웹페이지가 응답하지 않는 것을 방지하기 위해 이 파일을 비동기적으로 로드해야 함을 나타냅니다. IE는 이 속성을 지원하지 않고 defer만 지원하므로 defer도 작성한다.

require.js를 로드한 후 다음 단계는 자체 코드를 로드하는 것입니다. 우리 자신의 코드 파일이 main.js이고 js 디렉터리에도 있다고 가정합니다. 그런 다음 다음과 같이 작성하세요.

 

데이터 -main 속성은 웹 프로그램의 기본 모듈을 지정하는 데 사용됩니다. 위의 예에서는 js 디렉터리 아래의 main.js입니다. 이 파일은 require.js에 의해 먼저 로드됩니다. require.js의 기본 파일 확장자는 js이므로 main.js를 main으로 축약할 수 있습니다. ㅋㅋㅋ 이는 C 언어의 main() 함수와 약간 유사하며 모든 코드는 여기에서 실행되기 시작합니다.

main.js를 작성하는 방법을 살펴보겠습니다.

우리 코드가 다른 모듈에 의존하지 않는다면 자바스크립트 코드를 직접 작성할 수 있습니다. ㅋㅋㅋ 매우 일반적인 상황은 메인 모듈이 다른 모듈에 의존하는 경우이며, 이 경우 AMD 사양에 정의된 require() 함수를 사용해야 합니다.

   // main.js

  require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){

    // 여기에 일부 코드가 있습니다

 });

require() 함수는 두 개의 매개변수를 허용합니다. 첫 번째 매개변수는 의존하는 모듈을 나타내는 배열입니다. 위의 예는 ['moduleA', 'moduleB', 'moduleC']입니다. 즉, 주 모듈은 이 세 가지 모듈에 의존합니다. 두 번째 매개변수는 콜백입니다. 현재는 위에 지정된 모든 모듈이 성공적으로 로드된 후에 호출됩니다. 로드된 모듈은 이 함수에 매개변수로 전달되므로 이러한 모듈은 콜백 함수 내에서 사용할 수 있습니다.

require()는 moduleA, moduleB 및 moduleC를 비동기적으로 로드하며 브라우저는 응답을 잃지 않습니다. 지정된 콜백 함수는 이전 모듈이 성공적으로 로드된 후에만 실행되어 종속성 문제를 해결합니다.

이제 실제적인 예를 살펴보겠습니다.

기본 모듈이 jquery, underscore 및 backbone의 세 가지 모듈에 의존한다고 가정하면 main.js는 다음과 같이 작성할 수 있습니다.

 require(['jquery', 'underscore', 'backbone' ], 함수 ($, _, Backbone){

   // 여기에 코드가 있습니다

 });

require.js는 먼저 jQuery, 밑줄 및 백본을 로드한 다음 콜백 함수를 실행합니다. 콜백 함수에는 메인 모듈의 코드가 작성되어 있습니다.

4. 모듈 로딩

이전 섹션의 마지막 예에서 메인 모듈의 종속 모듈은 ['jquery', 'underscore', 'backbone']입니다. 기본적으로 require.js는 이 세 가지 모듈이 main.js와 동일한 디렉터리에 있고 파일 이름은 jquery.js, underscore.js 및 backbone.js라고 가정하고 자동으로 로드합니다.

require.config() 메소드를 사용하면 모듈의 로딩 동작을 사용자 정의할 수 있습니다. require.config()는 메인 모듈(main.js)의 선두에 작성됩니다. 매개변수는 객체이고, 이 객체의 paths 속성은 각 모듈의 로딩 경로를 지정합니다.

 require.config({

  paths: {

   "jquery": "jquery.min",
   "밑줄": " underscore.min",
   "백본" : "backbone.min"

  }

 });

위 코드는 세 모듈의 파일 이름을 제공합니다. 경로는 기본적으로 main.js(js)와 동일한 디렉터리입니다. 하위 디렉터리). 이러한 모듈이 js/lib 디렉토리와 같은 다른 디렉토리에 있는 경우 이를 작성하는 방법에는 두 가지가 있습니다. 하나는 경로를 하나씩 지정하는 것입니다.

require.config({

 ": "lib/underscore.min",

    "backbone": "lib/backbone.min"
  }
  } );

다른 하나는 기본 디렉터리(baseUrl)를 직접 변경하는 것입니다. " jquery.min",

   "underscore": "underscore.min",

  "backbone": "backbone.min"  }

  });

모듈이 다른 호스트에 있는 경우 다음과 같이 해당 URL을 직접 지정할 수도 있습니다.

 require.config({
  paths: {

   "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"

   });

require.js에는 다음이 필요합니다. 각 모듈은 별도의 js 파일입니다. 이 경우 여러 모듈이 로드되면 여러 HTTP 요청이 발행되며 이는 웹 페이지 로딩 속도에 영향을 미칩니다. 따라서 require.js는 모듈이 배포된 후 이 도구를 사용하여 여러 모듈을 하나의 파일로 병합하여 HTTP 요청 수를 줄일 수 있습니다.

5. AMD 모듈 작성 방법

require.js 모듈은 AMD 사양을 사용하여 로드됩니다. 즉, 모듈은 AMD 규정에 따라 작성되어야 합니다.

구체적으로 모듈은 특정 정의() 함수를 사용하여 정의해야 합니다. 모듈이 다른 모듈에 의존하지 않는 경우에는 Define() 함수에서 직접 정의할 수 있습니다.

이제 수학 모듈을 정의하는 math.js 파일이 있다고 가정합니다. 그러면 math.js는 다음과 같이 작성됩니다:

   // math.js

  Define(function (){

  var add = function (x,y){

    복귀 x +y;

  };

  반환 {

  추가: ​​추가

  };
 });

로딩 방법은 다음과 같습니다 :

// main.js

 require(['math'], function (math){

   Alert(math.add(1,1));

 }) ;

이 모듈이 다른 모듈에도 의존하는 경우, Define() 함수의 첫 번째 매개변수는 모듈의 종속성을 나타내는 배열이어야 합니다.

 define(['myLib'], function(myLib){

   function foo(){

   myLib.doSomething();

  }

   복귀 {

    foo : foo

  };

 });

require() 함수가 위 모듈을 로드할 때 myLib.js 파일을 먼저 로드합니다.

6. 비표준 모듈 로딩

이론적으로 require.js에 의해 로드되는 모듈은 AMD 사양에 따라 정의() 함수로 정의된 모듈이어야 합니다. 그러나 실제로 일부 인기 있는 함수 라이브러리(예: jQuery)는 이미 AMD 사양을 준수하지만 더 많은 라이브러리는 그렇지 않습니다. 그렇다면 require.js가 비표준 모듈을 로드할 수 있습니까?

답은 '예'입니다.

require()를 사용하여 이러한 모듈을 로드하기 전에 먼저 require.config() 메서드를 사용하여 일부 특성을 정의해야 합니다.

예를 들어 밑줄과 백본 두 라이브러리는 AMD 사양을 사용하여 작성되지 않았습니다. 이를 로드하려면 먼저 해당 특성을 정의해야 합니다.

 require.config({

   shim: {

   '밑줄': {
   내보내기: '_'
   },

   '백본': {
     deps: ['underscore', 'jquery'],
    내보내기: 'Backbone'
   }

  }

 });

require.config()수락 구성 개체에는 앞서 언급한 경로 속성 외에도 호환되지 않는 모듈을 구성하는 데 특별히 사용되는 shim 속성도 있습니다. 구체적으로 각 모듈은 (1) 외부에서 호출될 때 모듈의 이름을 나타내는 내보내기 값(출력 변수 이름), (2) 모듈의 종속성을 나타내는 deps 배열을 정의해야 합니다.

예를 들어 jQuery 플러그인은 다음과 같이 정의할 수 있습니다:

 '],

내보내기: 'jQuery.fn.scroll' 구현할 일련의 플러그인을 제공합니다. 특정 기능.

domready 플러그인을 사용하면 페이지 DOM 구조가 로드된 후 콜백 기능을 실행할 수 있습니다.

 require(['domready!'], function (doc){

     // DOM이 준비되면 호출됩니다

 });

텍스트 및 이미지 플러그인, 이를 통해 require.js가 텍스트 및 이미지 파일을 로드할 수 있습니다.

 define([

    'text!review.txt',

    'image!cat.jpg'

    ],

    function(review,cat){

      console.log(review);

      document.body.appendChild(cat);

    }

  );

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

另一个人的概括(有点简单):

AMD就只有一个接口:define(id?,dependencies?,factory);

它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,像这样:

1 define([&#39;dep1&#39;,&#39;dep2&#39;],function(dep1,dep2){...});
로그인 후 복사

要是没什么依赖,就定义简单的模块,下面这样就可以啦:

<span style="font-family:&#39;幼圆&#39;;font-size:16px;">1 define(function(){<br/>2     var exports = {};<br/>3     exports.method = function(){...};<br/>4     return exports;<br/>5 });</span>
로그인 후 복사

咦,这里有define,把东西包装起来啦,那Node实现中怎么没看到有define关键字呢,它也要把东西包装起来呀,其实吧,只是Node隐式包装了而已.....

这有AMD的WIKI中文版,讲了很多蛮详细的东西,用到的时候可以查看:AMD的WIKI中文版

三、CMD

大名远扬的玉伯写了seajs,就是遵循他提出的CMD规范,与AMD蛮相近的,不过用起来感觉更加方便些,最重要的是中文版,应有尽有:seajs官方doc

1 define(function(require,exports,module){...});
로그인 후 복사

用过seajs吧,这个不陌生吧,对吧。

前面说AMD,说RequireJS实现了AMD,CMD看起来与AMD好像呀,那RequireJS与SeaJS像不像呢?

虽然CMD与AMD蛮像的,但区别还是挺明显的,官方非官方都有阐述和理解,我觉得吧,说的都挺好:

官方阐述SeaJS与RequireJS异同

SeaJS与RequireJS的最大异同(这个说的也挺好)

相关推荐:

理解前端模块化(CommonJs,AMD和CMD)

JavaScript模块规范之AMD规范和CMD规范

위 내용은 JS(CommonJS, AMD, CMD)의 모듈 사양에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!