這篇文章帶給大家的內容是關於Javascript模組化的詳細介紹 ,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
前言
隨著Web 技術的蓬勃發展和依賴的基礎設施日益完善,前端領域逐漸從瀏覽器擴展至服務端(Node.js),桌面端(PC、Android 、iOS),甚至於物聯網設備(IoT),其中JavaScript 承載著這些應用程式的核心部分,隨著其規模化和複雜度的成倍增長,其軟體工程體係也隨之建立起來(協同開發、單元測試、需求和缺陷管理等),模組化程式的需求日益迫切。
JavaScript 對模組化程式設計的支援尚未形成規範,難以堪此重任;一時間,江湖俠士挺身而出,一路披荊斬棘,從刀耕火種過渡到面向未來的模組化方案;
概念
模組化程式設計就是透過組合一些__相對獨立可重複使用的模組__來進行功能的實現,其最核心的兩個部分是__定義模組__和__引入模組__;
定義模組時,每個模組內部的執行邏輯是不被外部感知的,只是導出(暴露)出部分方法和資料;
引入模組時,同步/ 非同步去載入待引入的程式碼,執行並取得到其暴露的方法和資料;
刀耕火種
儘管JavaScript 語言層面並未提供模組化的解決方案,但利用其可__物件導向__的語言特性,外加__設計模式_ _加持,能夠實現一些簡單的模組化的架構;經典的一個案例是利用單例模式模式去實現模組化,可以對模組進行較好的封裝,只暴露部分資訊給需要使用模組的地方;
// Define a module var moduleA = (function ($, doc) { var methodA = function() {}; var dataA = {}; return { methodA: methodA, dataA: dataA }; })(jQuery, document); // Use a module var result = moduleA.mehodA();
直觀來看,透過立即執行函數(IIFE)來聲明依賴以及導出數據,這與當下的模組化方案並無巨大的差異,可本質上卻有千差萬別,無法滿足的一些重要的特性;
定義模組時,宣告的依賴不是強制自動引入的,即在定義該模組之前,必須手動引入依賴的模組程式碼;
-
定義模組時,其程式碼就已經完成執行過程,無法實現按需載入;
#跨檔案使用模組時,需要將模組掛載到全域變數(window)上;
AMD & CMD 二分天下
題外話:由於年代久遠,這兩種模組化方案逐漸淡出歷史舞台,具體特性不再細聊;為了解決」刀耕火種」時代存留的需求,AMD 和CMD 模組化規範問世,解決了在瀏覽器端的異步模組化編程的需求,__其最核心的原理是通過動態加載script 和事件監聽的方式來異步載入模組;__
AMD 和CMD 最具代表的兩個作品分別對應require.js 和sea.js;其主要區別在於依賴宣告和依賴載入的時機,其中require.js 預設在宣告時執行, sea.js 推崇懶加載和按需使用;另外值得一提的是,CMD 規範的寫法和CommonJS 極為相近,只需稍作修改,就能在CommonJS 中使用。參考下面的Case 更有助於理解;
// AMD define(['./a','./b'], function (moduleA, moduleB) { // 依赖前置 moduleA.mehodA(); console.log(moduleB.dataB); // 导出数据 return {}; }); // CMD define(function (requie, exports, module) { // 依赖就近 var moduleA = require('./a'); moduleA.mehodA(); // 按需加载 if (needModuleB) { var moduleB = requie('./b'); moduleB.methodB(); } // 导出数据 exports = {}; });
CommonJS
2009 年ty 發布Node.js 的第一個版本,CommonJS 作為其中最核心的特性之一,適用於服務端下的場景;歷年來的考察和時間的洗禮,以及前端工程化對其的充分支持,CommonJS 被廣泛運用於Node.js 和瀏覽器;
// Core Module const cp = require('child_process'); // Npm Module const axios = require('axios'); // Custom Module const foo = require('./foo'); module.exports = { axios }; exports.foo = foo;
規範
##module (Object): 模組本身
exports (*): 模組的匯出部分,也就是揭露的內容
require (Function): 載入模組的函數,取得目標模組的匯出值(基礎型別為複製,引用型別為淺拷貝),可以載入內建模組、npm 模組和自訂模組
實作
1、模組定義
- 預設任意.node .js .json 檔案都是符合規範的模組;
-
2、引入模組
先從快取(require.cache)優先讀取模組,如果未命中緩存,則進行路徑分析,然後按照不同類型的模組處理: - 內建模組,直接從記憶體載入;
-
###外部模組,先進行檔案尋址定位,然後進行編譯和執行,最終得到對應的匯出值;########### #其中在編譯的過程中,Node對獲取的JavaScript檔案內容進行了頭尾包裝,結果如下:###
(function (exports, require, module, __filename, __dirname) { var circle = require('./circle.js'); console.log('The area of a circle of radius 4 is ' + circle.area(4)); });
###特性總結############同步執行模組聲明和引入邏輯,分析一些複雜的依賴引用(如循環依賴)時需注意;############快取機制,效能更優,同時限制了記憶體佔用;######## #####Module 模組可供改造的靈活度高,可以實現一些客製化需求(如熱更新、任意檔案類型模組支援);###
ES Module(推荐使用)
ES Module 是语言层面的模块化方案,由 ES 2015 提出,其规范与 CommonJS 比之 ,导出的值都可以看成是一个具备多个属性或者方法的对象,可以实现互相兼容;但写法上 ES Module 更简洁,与 Python 接近;
import fs from 'fs'; import color from 'color'; import service, { getArticles } from '../service'; export default service; export const getArticles = getArticles;
主要差异在于:
ES Module 会对静态代码分析,即在代码编译时进行模块的加载,在运行时之前就已经确定了依赖关系(可解决循环引用的问题);
ES Module 关键字:
import
export
以及独有的default
关键字,确定默认的导出值;ES Module 中导入模块的属性或者方法是强绑定的,包括基础类型;
UMD
通过一层自执行函数来兼容各种模块化规范的写法,兼容 AMD / CMD / CommonJS 等模块化规范,贴上代码胜过千言万语,需要特别注意的是 ES Module 由于会对静态代码进行分析,故这种运行时的方案无法使用,此时通过 CommonJS 进行兼容;
(function (global, factory) { if (typeof exports === 'object') { module.exports = factory(); } else if (typeof define === 'function' && define.amd) { define(factory); } else { this.eventUtil = factory(); } })(this, function (exports) { // Define Module Object.defineProperty(exports, "__esModule", { value: true }); exports.default = 42; });
构建工具中的实现
为了在浏览器环境中运行模块化的代码,需要借助一些模块化打包的工具进行打包( 以 webpack 为例),定义了项目入口之后,会先快速地进行依赖的分析,然后将所有依赖的模块转换成浏览器兼容的对应模块化规范的实现;
模块化的基础
从上面的介绍中,我们已经对其规范和实现有了一定的了解;在浏览器中,要实现 CommonJS 规范,只需要实现 module / exports / require / global 这几个属性,由于浏览器中是无法访问文件系统的,因此 require 过程中的文件定位需要改造为加载对应的 JS 片段(webpack 采用的方式为通过函数传参实现依赖的引入)。具体实现可以参考:tiny-browser-require。
webpack 打包出来的代码快照如下,注意看注释中的时序;
(function (modules) { // The module cache var installedModules = {}; // The require function function __webpack_require__(moduleId) {} return __webpack_require__(0); // ---> 0 }) ({ 0: function (module, exports, __webpack_require__) { // Define module A var moduleB = __webpack_require__(1); // ---> 1 }, 1: function (module, exports, __webpack_require__) { // Define module B exports = {}; // ---> 2 } });
实际上,ES Module 的处理同 CommonJS 相差无几,只是在定义模块和引入模块时会去处理 __esModule 标识,从而兼容其在语法上的差异。
异步和扩展
1、浏览器环境下,网络资源受到较大的限制,因此打包出来的文件如果体积巨大,对页面性能的损耗极大,因此需要对构建的目标文件进行拆分,同时模块也需要支持动态加载;
webpack 提供了两个方法 require.ensure() 和 import() (推荐使用)进行模块的动态加载,至于其中的原理,跟上面提及的 AMD & CMD 所见略同,import() 执行后返回一个 Promise 对象,其中所做的工作无非也是动态新增 script 标签,然后通过 onload / onerror 事件进一步处理。
2、由于 require 函数是完全自定义的,我们可以在模块化中实现更多的特性,比如通过修改 require.resolve 或 Module._extensions 扩展支持的文件类型,使得 css / .jsx / .vue / 图片等文件也能为模块化所使用;
附录:特性一览表
模块化规范 | 加载方式 | 加载时机 | 运行环境 | 备注 |
---|---|---|---|---|
AMD | 异步 | 运行时 | 浏览器 | |
CMD | 异步 | 运行时 | 浏览器 | |
CommonJS | 同步/异步 | 运行时 | 浏览器 / Node | |
ES Module | 同步/异步 | 编译阶段 | 浏览器 / Node | 通过 import() 实现异步加载 |
相关推荐:
javascript模块化编程(转载),javascript模块化
以上是Javascript模組化的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

記事本++7.3.1
好用且免費的程式碼編輯器

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3漢化版
中文版,非常好用

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能