検索
ホームページウェブフロントエンドjsチュートリアルモジュール性は JS でどのように実装されますか?

モジュール性は JS でどのように実装されますか?

Jan 09, 2018 pm 05:01 PM
javascript成し遂げるモジュラー

Js の初期の位置付け (当初は過度に複雑なシナリオで使用されるとは想定していませんでした) により、モジュール システムは提供されません。アプリケーションがより複雑になるにつれて、モジュール化は解決しなければならない問題になります。 Feimai の徹底した原則に従って、モジュール化のベールを取り除く必要があります。この記事では、主に Js でのモジュール化がどのように詳細に実装されているかを紹介し、一定の参考値を持つモジュール化の操作を詳細に紹介します。興味のある方はさらに詳しく学んで、皆さんのお役に立てれば幸いです。

1. モジュール化によって解決すべき問題

何かを深く分析するには、目的を持って見る必要があります。モジュール化によって解決される問題は、一文に要約できます

地球規模の汚染を発生させずに、プロジェクト コードをより適切に構成できます

簡単な例を挙げると、次のコードができました:

function doSomething () {
 const a = 10;
 const b = 11;
 const add = function (a + b) {
  return a + b
 }
 add (a + b)
}

実際のアプリケーション内 シナリオ内、 doSomething は非常に多くのことを実行する必要がある可能性があり、追加関数はより複雑で再利用できる可能性があるため、追加関数を別のファイルに分離したいと考えています:

// doSomething.js 文件
const add = require('add.js');
const a = 10;
const b = 11;
add(a+ b);
// add.js 文件
function add (a, b) {
 return a + b;
}
module.exports = add;

これの目的は明らかです。プロジェクト コードをよりよく整理し、2 つのファイル内の require と module.exports に注目してください。現在の観点から見ると、これは CommonJS 仕様のキーワードから来ています (この仕様については後で説明する章があります)。これらはインポートとエクスポートを表します。仕様に関係なく、これは実際にはモジュール化に向けて解決する必要がある問題です。さらに、add モジュールは再利用する必要がありますが、add を導入するときに地球規模の汚染を引き起こすことは望ましくありません

2. インポートされたモジュールを実行する方法

上記の例では、コードを 2 つのモジュールに分割しています。ファイルを地球規模の汚染を引き起こすことなく、例のコードが正常に実行できるように require を実装するにはどうすればよいでしょうか?

モジュールファイルのコードの読み込みプロセスを無視し、requireがすでにモジュールファイルからコード文字列を読み取ることができると仮定すると、requireは次のように実装できます

function require (path) {
  // lode 方法读取 path 对应的文件模块的代码字符串
  // let code = load(path);
  // 不考虑 load 的过程,直接获得模块 add 代码字符串
  let code = 'function add(a, b) {return a+b}; module.exports = add';
  // 封装成闭包
  code = `(function(module) {$[code]})(context)`
  // 相当于 exports,用于导出对象
  let context = {};
  // 运行代码,使得结果影响到 context
  const run = new Function('context', code);
  run(context, code);
  //返回导出的结果
  return context.exports;
}

いくつかのポイントがあります:

1)原因 グローバル汚染の場合、コード文字列をクロージャの形式でカプセル化する必要があり、キーワード module.exports をエクスポートする必要があります。モジュールは、外部との接触の唯一のキャリアです。これを入力として使用する必要があります。クロージャ匿名関数のパラメータとリファラーによって渡されるコンテキストの関連付け

2) new Function を使用してコード文字列を実行する 一般的にはその必要がないため、ほとんどの学生は new Function に慣れていないものと推定されます。これは関数を定義するためのものです。次のように関数クラスを使用して関数を作成できることを知っておく必要があります。

var function_name = new function(arg1, arg2, ..., argN, function_body)

上記の形式では、各引数はパラメーターであり、最後のパラメーターは関数本体 (関数のコード) です。実行されます)。これらのパラメータは文字列である必要があります。つまり、eval と同様に文字列コードを実行するために使用でき、eval と比較して、文字列コード内の特定の変数の値をパラメーターの形式で渡すこともできます

3)標準のエクスポート キーワードはエクスポートのみであるのに、実際の使用では module.exports を使用する必要があるのはなぜだろうかという疑問を抱いたことがあるでしょう (Node コードを書いたことがある人はよく知っているはずです)。その場合は、このコードで答えを見つけることができます。 use exports コンテキストを受信すると、エクスポートの再割り当てはコンテキストに影響を与えません (パラメーターのアドレスが渡されます)。信じられない場合は、コードを次の形式に変更して再実行してください。

デモの結果

3. コードのロード方法

コードの実行の問題を解決するには、モジュール ファイルのコードのロードの問題も解決する必要があります。上記の例によれば、私たちの目標はモジュールをロードすることです。文字列形式のファイル コード

Node コンテナでは、すべてのモジュール ファイルはローカルにあります。ローカル ディスクからモジュール ファイルを読み取って文字列コードをロードし、上記のプロセスに従うだけです。事実は、Node の非組み込みモジュール、コアモジュール、および C++ モジュールのロードと実行メソッドがほぼ同じであることを証明しています (新しい関数ではありませんが、同様のメソッドです)

RN/Weex コンテナでは、リモートのbundle.jsをロードする必要がある場合、ネイティブの機能を通じてリモートjsファイルをリクエストし、それを文字列コードに読み込んでロードできます(このロジックによれば、Nodeはリモートjsモジュールを読み取ることができるように見えますが)ほとんどの場合、これを行う必要はありません)

ブラウザ環境では、すべての JS モジュールをリモートで読み取る必要がありますが、残念ながら、ブラウザが提供する機能の制限により、リモート JS ファイルを次の形式で直接読み取ることができません。 ajax を介したファイル ストリームは文字列コードです。前提条件が満たされない場合、上記の運用戦略は機能せず、別の方法を見つけるしかありません

これが CommonJs 仕様が存在する理由であり、AMD/CMD 仕様も存在する理由です


それではどうでしょうかブラウザ上で完了しますか?ブラウザの Js コントロールを通じてリモート Js モジュール ファイルを動的にロードするには、<script> ノードを動的に挿入する必要があります。<pre class="brush:php;toolbar:false">// 摘抄自 require.js 的一段代码 var node = config.xhtml ? document.createElementNS(&amp;#39;http://www.w3.org/1999/xhtml&amp;#39;, &amp;#39;html:script&amp;#39;) : document.createElement(&amp;#39;script&amp;#39;); node.type = config.scriptType || &amp;#39;text/javascript&amp;#39;; node.charset = &amp;#39;utf-8&amp;#39;; node.async = true; node.setAttribute(&amp;#39;data-requirecontext&amp;#39;, context.contextName); node.setAttribute(&amp;#39;data-requiremodule&amp;#39;, moduleName); node.addEventListener(&amp;#39;load&amp;#39;, context.onScriptLoad, false); node.addEventListener(&amp;#39;error&amp;#39;, context.onScriptError, false);&lt;p&gt;要知道,设置了 &lt;script&gt; 标签的 src 之后,代码一旦下载完成,就会立即执行,根本由不得你再封装成闭包,所以文件模块需要在定义之初就要做文章,这就是我们说熟知的 AMD/CMD 规范中的 define,开篇的 add.js 需要重新改写一下&lt;/script&gt;&lt;/p&gt; &lt;pre class=&quot;brush:php;toolbar:false&quot;&gt;// add.js 文件 define ('add',function () {   function add (a, b) {    return a + b;   }   return add; })</pre> <p>而对于 define 的实现,最重要的就是将 callback 的执行结果注册到 context 的一个模块数组中:</p> <pre class="brush:php;toolbar:false">  context.modules = {}   function define(name, callback) {     context.modules[name] = callback &amp;&amp; callback()   }</pre> <p>于是 require 就可以从 context.modules 中根据模块名载入模块了,是不是有了一种自己去写一个 “requirejs” 的冲动感</p> <p>具体的 AMD 实现当然还会复杂很多,还需要控制模块载入时序、模块依赖等等,但是了解了这其中的灵魂,想必去精读 require.js 的源码也不是一件困难的事情</p> <p>四、Webpack 中的模块化</p> <p>Webpack 也可以配置异步模块,当配置为异步模块的时候,在浏览器环境同样的是基于动态插入 <script> 的方式载入远程模块。在大多数情况下,模块的载入方式都是类似于 Node 的本地磁盘同步载入的方式</script>

嫑忘记,Webpack 除了有模块化的能力,还是一个在辅助完善开发工作流的工具,也就是说,Webpack 的模块化是在开发阶段的完成的,使用 Webpack 构筑的工作环境,在开发阶段虽然是独立的模块文件,但是在运行时,却是一个合并好的文件

所以 Webpack 是一种在非运行时的模块化方案(基于 CommonJs),只有在配置了异步模块的时候对异步模块的加载才是运行时的(基于 AMD)

五、模块化规范

通用的问题在解决的过程中总会形成规范,上文已经多次提到 CommonJs、AMD、CMD,有必要花点篇幅来讲一讲规范

Js 的模块化规范的萌发于将 Js 扩展到后端的想法,要使得 Js 具备类似于 Python、Ruby 和 Java 那样具备开发大型应用的基础能力,模块化规范是必不可少的。CommonJS 规范的提出,为Js 制定了一个美好愿景,希望 Js 能在任何地方运行,包括但不限于:

  • 服务器端 Js 应用

  • 命令行工具

  • 桌面应用

  • 混合应用

CommonJS 对模块的定义并不复杂,主要分为模块引用、模块定义和模块标识

  1. 模块引用:使用 require 方法来引入一个模块

  2. 模块定义:使用 exports 导出模块对象

  3. 模块标识:给 require 方法传入的参数,小驼峰命名的字符串、相对路径或者绝对路径

模块示意

CommonJs 规范在 Node 中大放异彩并且相互促进,但是在浏览器端,鉴于网络的原因,同步的方式加载模块显然不太实用,在经过一段争执之后,AMD 规范最终在前端场景中胜出(全称 Asynchronous Module Definition,即“异步模块定义”)

什么是 AMD,为什么需要 AMD ?在前述模块化实现的推演过程中,你应该能够找到答案

除此之外还有国内玉伯提出的 CMD 规范,AMD 和 CMD 的差异主要是,前者需要在定义之初声明所有的依赖,后者可以在任意时机动态引入模块。CMD 更接近于 CommonJS

两种规范都需要从远程网络中载入模块,不同之处在于,前者是预加载,后者是延迟加载

相关推荐:

javascript高级模块化require.js的具体使用方法实例分享

Laravel 的模块化开发框架 Notadd RC1

JavaScript使用高级模块化require.js的具体方法详解

以上がモジュール性は JS でどのように実装されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境