ホームページ > ウェブフロントエンド > jsチュートリアル > JS(CommonJS、AMD、CMD)でのモジュール仕様の詳細説明

JS(CommonJS、AMD、CMD)でのモジュール仕様の詳細説明

php是最好的语言
リリース: 2018-08-07 09:21:44
オリジナル
2017 人が閲覧しました

最初に答えてください: モジュールはなぜ重要ですか?

答え: モジュールのおかげで、他の人のコードをより便利に使用でき、必要な機能に必要なモジュールをロードできます。
ただし、これには前提があります。つまり、全員が同じ方法でモジュールを書かなければなりません。そうでないと、あなたにはあなたの書き方があり、私には私の書き方がある、ということです。

そこで、以下の 3 つのモジュールが標準化され、この記事も公開されました ({顔を覆って笑う}と綴られています)。

JS のモジュール仕様 (CommonJS、AMD、CMD)、JS のモジュール化について聞いたことがあるなら、CommonJS や AMD、さらには CMD についても聞いたことがあるはずです。それを聞いただけです。 これらの仕様がどのようなもので、どのような機能があるのか​​を見てみましょう。この記事には、これら 3 つの仕様の出典と、それらに対応する製品の原理が含まれています。

1. CommonJS

1. 最初は、公式に定義された API はブラウザベースのアプリケーションしか構築できないと誰もが考えていました。これはあまりにも CommonJS は視野が狭すぎるため (高級な言葉を使って、インチキ)、CommonJS API は通常のアプリケーション (主にブラウザ以外のアプリケーション) で使用される多くの API を定義しており、このギャップを埋めています。その最終的な目標は、Python、Ruby、Java に似た標準ライブラリを提供することです。この場合、開発者は CommonJS API を使用してアプリケーションを作成し、これらのアプリケーションを異なる JavaScript インタープリターや異なるホスト環境で実行できます。

CommonJS と互換性のあるシステムでは、JavaScript を使用して次のプログラムを開発できます: サーバーサイド JavaScript アプリケーション

(2)。グラフィック インターフェイス アプリケーション

(4). ハイブリッド アプリケーション (Titanium や Adob​​e AIR など)
2009 年に、アメリカのプログラマー Ryan Dahl は、サーバーサイド プログラミングに JavaScript 言語を使用するために、node.js プロジェクトを作成しました。これにより、「JavaScript モジュール型プログラミング」が正式に誕生しました。正直に言うと、ブラウザ環境ではモジュールがなくても大きな問題はありませんが、Web プログラムの複雑さは制限されていますが、サーバー側ではオペレーティング システムや他のアプリケーションと対話するためのモジュールが必要です。そうでなければプログラミングはできません。 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() は外部モジュールを導入するために使用され、exports オブジェクトは現在のモジュールのメソッドまたは変数をエクスポートするために使用され、モジュール オブジェクトはモジュール自体を表します。

Node は CommonJS の仕様に従っていますが、いくつかのトレードオフが行われ、いくつかの新しいものが追加されています。

しかし、CommonJS について話し、Node についても話した後は、まず NPM を理解する必要があると思います。 Node のパッケージ マネージャーとして、NPM は Node が依存するパッケージのインストールの問題を解決するのを支援するものではなく、CommonJS 仕様 (または理論) に従う必要があります。 CommonJS WIKI ではその歴史を語り、モジュールやパッケージなども紹介しています。

commonJS の原理と簡単な実装について話しましょう:

1. 原則

ブラウザーが CommonJS と互換性がない根本的な理由は、4 つの Node.js 環境変数が欠如していることです。

  • モジュール

  • エクスポート

  • 必須

  • グローバル

これら 4 つの変数を提供できる限り、ブラウザーは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 と exports という 2 つの外部変数を提供し、モジュールはこの即時実行関数に配置されます。 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 とは具体的に何をするのですか?ブラウザーアンパックをインストールすると、はっきりと見ることができます。

<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 属性はモジュールの依存関係です。モジュール。

main.jsにはfoo.jsが読み込まれているため、deps属性で./fooがモジュール1番に対応することが指定されています。実行中、ブラウザはrequire('./foo')文を検出すると、モジュールNo.1のsource属性を自動的に実行し、実行されたmodule.exports属性値を出力します。 3. 小さなブラウザが必要です

Browserify は非常に強力ですが、ブラウザでは操作できないため、非常に不便な場合があります。

mocha の内部実装に基づいて、純粋なブラウザ 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 仕様を実装する 2 つの主要な Javascript ライブラリ、require.js とcurl.js があります。

RequireJS は AMD 仕様を実装します。

詳細な概要: 以下では、AMD 仕様を説明するための例として RequireJS を使用しています

1. require.js を使用する理由?

初期の頃、すべての Javascript コードは 1 つのファイルに記述されており、この 1 つのファイルを読み込むだけで十分でした。その後、コードがどんどん増え、1 つのファイルでは不十分になり、複数のファイルに分割して順番にロードする必要がありました。次の Web ページのコードを見たことがある方も多いと思います




< ; script src="5.js">

このコードは複数の js を順番に読み込みます書類。

この書き方には大きな欠点があります。まず、ロード時にブラウザは Web ページのレンダリングを停止します。ロードされるファイルが増えると、Web ページの応答が失われる時間が長くなります。次に、js ファイル間の依存関係により、ロード順序が厳密に保証される必要があります。上記の例のように、1.js は 2.js の前に置く必要があり、依存関係が最も大きいモジュールを最後に読み込む必要があります。依存関係が複雑になると、コードの記述とメンテナンスが困難になります。

require.js は、次の 2 つの問題を解決するために生まれました:

(1) Web ページが応答しなくなることを避けるために、js ファイルの非同期読み込みを実装します。 (2)モジュール間の依存関係を管理して、コードの作成とメンテナンスを容易にします。

2. require.js の読み込み

require.js を使用する最初のステップは、公式 Web サイトにアクセスして最新バージョンをダウンロードすることです。

ダウンロード後、jsサブディレクトリ配下に置くと読み込めると思われます。

このファイルを読み込むと Web ページが応答しなくなる可能性があると考える人もいるかもしれません。解決策は 2 つあり、1 つは Web ページの下部にロードする方法、もう 1 つは次のように記述する方法です:

async 属性は、Web ページが応答しなくなるのを避けるために、このファイルを非同期でロードする必要があることを示します。 IE はこの属性をサポートしておらず、defer のみをサポートしているため、defer とも記述されます。

require.js をロードしたら、次のステップは独自のコードをロードすることです。独自のコード ファイルが main.js であり、これも js ディレクトリの下に配置されていると仮定します。あとは、次のように書くだけです:

データ-main 属性は、Web プログラムのメイン モジュールを指定するために使用されます。上記の例では、js ディレクトリ内の main.js が、require.js によって最初に読み込まれます。 require.js のデフォルトのファイル拡張子は js であるため、main.js は main と省略できます。

3. メインモジュールの書き方

前節の main.js を、Web ページ全体のエントリーコードを意味する「メインモジュール」と呼びます。これは C 言語の main() 関数に似ており、すべてのコードはここから実行を開始します。

main.jsの書き方を見てみましょう。

コードが他のモジュールに依存していない場合は、JavaScript コードを直接記述することができます。

// main.js

alert("Loaded fully!");

ただし、この場合、require.jsを使用する必要はありません。本当に一般的な状況は、メイン モジュールが他のモジュールに依存することです。その場合、AMD 仕様で定義されている require() 関数を使用する必要があります。

// main.js

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

// ここにいくつかのコード

});

require() 関数は 2 つのパラメータを受け取ります。最初のパラメータは配列であり、依存するモジュールを示します。上記の例は ['moduleA', 'moduleB', 'moduleC'] です。つまり、メイン モジュールはこれら 3 つのモジュールに依存します。現在、この関数は上記で指定されたすべてのモジュールが正常にロードされた後に呼び出されます。ロードされたモジュールはパラメータとしてこの関数に渡されるため、これらのモジュールはコールバック関数内で使用できます。

require() は moduleA、moduleB、および moduleC を非同期的にロードします。ブラウザは応答を失いません。指定されたコールバック関数は、前のモジュールが正常にロードされた後にのみ実行され、依存関係の問題が解決されます。

それでは、実際の例を見てみましょう。

メインモジュールが jquery、underscore、backbone の 3 つのモジュールに依存すると仮定すると、main.js は次のように記述できます:

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

// ここにいくつかのコード

});

require.js は、まず jQuery、アンダースコア、バックボーンをロードしてから、コールバック関数を実行します。メインモジュールのコードはコールバック関数内に記述されます。

4. モジュールの読み込み

前のセクションの最後の例では、メインモジュールの依存モジュールは ['jquery', 'underscore', 'backbone'] です。デフォルトでは、require.js は、これら 3 つのモジュールが main.js と同じディレクトリにあり、ファイル名が jquery.js、underscore.js、backbone.js であると想定し、自動的にロードします。

require.config() メソッドを使用すると、モジュールの読み込み動作をカスタマイズできます。 require.config()はメインモジュール(main.js)の先頭に記述されます。パラメータはオブジェクトであり、このオブジェクトの paths 属性は各モジュールのロード パスを指定します。

require.config({

paths: {

"jquery": "jquery.min",
"underscore": "underscore.min",
「背骨」 : "backbone.min"

}

});

上記のコードは、3 つのモジュールのファイル名を指定します。パスのデフォルトは main.js (js.サブディレクトリ)。これらのモジュールが js/lib ディレクトリなどの他のディレクトリにある場合、モジュールを記述する方法は 2 つあります。 1 つはパスを 1 つずつ指定する方法です。

require.config({

": "lib/underscore.min",

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

もう 1 つは、ベース ディレクトリ (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 リクエストが発行されるため、Web ページの読み込み速度に影響します。したがって、require.js には最適化ツールが用意されており、モジュールをデプロイした後、このツールを使用して複数のモジュールを 1 つのファイルにマージし、HTTP リクエストの数を減らすことができます。

5. AMD モジュールの書き方

require.js モジュールは AMD 仕様を使用してロードされます。つまり、モジュールは AMD の規定に従って作成する必要があります。

具体的には、モジュールは特定のdefine()関数を使用して定義する必要があります。モジュールが他のモジュールに依存していない場合は、define() 関数で直接定義できます。

数学モジュールを定義する math.js ファイルがあると仮定します。すると、 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();

}

戻る{

foo : foo

};

});

require() 関数が上記のモジュールをロードすると、最初に myLib.js ファイルがロードされます。

6. 非標準モジュールのロード

理論的には、require.js によってロードされるモジュールは、AMD 仕様に従って、define() 関数で定義されたモジュールである必要があります。しかし実際には、一部の一般的な関数ライブラリ (jQuery など) はすでに AMD 仕様に準拠していますが、さらに多くのライブラリは準拠していません。では、require.js は非標準モジュールを読み込むことができるのでしょうか?

答えは「はい」です。

このようなモジュールを require() でロードする前に、まず require.config() メソッドを使用してその特性の一部を定義する必要があります。

たとえば、2 つのライブラリのアンダースコアとバックボーンは、AMD 仕様を使用して書かれていません。それらをロードする場合は、まずその特性を定義する必要があります。

require.config({

shim: {

'underscore': {
exports: '_'
},

「バックボーン」: {
deps: ['underscore', 'jquery'],
exports: 'バックボーン'
}

}

});

require.config() accept構成オブジェクト。前述の paths 属性に加えて、このオブジェクトには互換性のないモジュールを構成するために特別に使用される shim 属性もあります。具体的には、各モジュールは、(1) 外部から呼び出されるモジュールの名前を示すエクスポート値 (出力変数名)、(2) モジュールの依存関係を示す deps 配列を定義する必要があります。

たとえば、jQuery プラグインは次のように定義できます:

'],

エクスポート: 'jQuery.fn.scroll' 実装する一連のプラグインを提供します何らかの特定の機能。

domready プラグインを使用すると、ページ DOM 構造がロードされた後にコールバック関数を実行できます。 burect(['domready!']、function(doc){

// domが準備ができたら});

textと画像プラグイン、これにより、require.js がテキスト ファイルと画像ファイルを読み込めるようになります。

定義([

    '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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート