首頁  >  文章  >  web前端  >  JS模組化-RequireJS

JS模組化-RequireJS

php中世界最好的语言
php中世界最好的语言原創
2018-03-07 09:43:211996瀏覽

今天帶給大家JS模組化-RequireJS,關於JS模組化的注意事項有哪些,應該如何使用RequireJS?下面就是實戰案例,一起來看一下。

之前一直有聽說RequireJS,但一直都沒機會去了解,只知道它是一個給js做模組化的API。最近在做React,其組件化的思想和js模組化的思想不謀而合。就想在專案中應用React的同時,也把RequireJS加進來,看看會不會對頁面載入或開發有很好的效果。

What is RequireJS?

在說明什麼是RequireJS之前,我不得不提的就是Javascript模組化歷史的背景。其實在早期,javascript作為一門新興的腳本語言出現,有著龐大的願景,它並不是作為一門僅僅針對客戶端設計的語言。只是說後來web應用的流行,javascript作為瀏覽器端腳本語言而迅速傳開,加上Netscape和微軟的競爭將其過早的標準化。所以就導致了JS的諸多缺陷,其中一個就是模組化(但是你可以驚奇地發現其實javascript有將import,export等作為保留字,說明設計的時候其實是有考慮的,新的標準es6也讓原生支援模組化了)。然後隨著web應用越來越複雜,嵌入的javascript程式碼越來越多,還有node的興起,模組化程式設計就變成了必須。

所以就有了後來Dojo工具包和Google的Closure庫支援的模組系統。還有兩個非常通用的標準規範,CommonJS和AMD。這裡就不展開說了,我們只需要知道,實作CommonJS規範的API是同步載入模組的,而實作AMD規範的API是則是非同步載入模組。
所以理論上來說,AMD規範的非阻塞載入更適合瀏覽器端。而RequireJS就是AMD規範的最好實作。抄一段官方文件對RequireJS的描述:

RequireJS 是JavaScript模組載入器。它非常適合在瀏覽器中使用, 它非常適合在瀏覽器中使用,但它也可以用在其他腳本環境, 就像 Rhino and Node. 使用RequireJS加載模組化腳本將提高代碼的加載速度和質量。

Why RequireJS?

所以,知道了RequireJS是做什麼的,也差不多知道為什麼我們要使用RequireJS了。不過還是總結一下用RequireJS的好處吧。

非同步「載入」。我們知道,通常網站都會把script腳本的放在html的最後,這樣就可以避免瀏覽器執行js帶來的頁面阻塞。使用RequireJS,會在相關的js載入後執行回呼函數,這個過程是異步的,所以它不會阻塞頁面。

按需載入。透過RequireJS,你可以在需要載入js邏輯的時候再載入對應的js模組,這樣避免了在初始化網頁的時候發生大量的請求和資料傳輸,或許對某些人來說,某些模組可能他根本就不需要,那就顯得沒有必要。

更方便的模組依賴管理。相信你曾經一定遇過因為script標籤順序問題而導致依賴關係發生錯誤,這個函數未定義,那個變數undefine之類的。透過RequireJS的機制,你能確保在所有的依賴模組都載入以後再執行相關的文件,所以可以起到依賴管理的作用。

更有效率的版本管理。想一想,如果你還是用的script腳本引入的方式來引入一個jQuery2.x的文件,然後你有100個頁面都是這麼引用的,那當你想換成jQuery3.x,那你就不得不去改這100個頁面。但是如果你的requireJS有在config中做jQuery的path映射,那就只要改一處地方即可。

當然還有一些諸如cdn載入不到js文件,可以請求本地文件等其它的優點,這裡就不一一列舉了。

RequireJS 使用

需要在頁面中引入的檔案

<script data-main="js/main" src="xxx/xxxx/require.js"></script>

使用RequireJS,你只需要引入一個require.js。要說明的是,一個比較好的實踐,就是你的頁面上面應該也只需要透過3f1c4e4b6b16bbbd69b2ee476dc4f83a標籤來引入這一個js即可。然後你這個頁面的所有業務邏輯只要在main.js裡面寫(data-main屬性作用後面會有講)就可以了。其它所引用的依賴怎麼辦?當然是透過require按需引入啊!

Require基本上概述

其實Requirejs整個原始檔包含註解就2000來行,其對外暴露的變數其實就三個,requirejs,require,define。

這其中requirejs 只是require的一個別名,目的是如果頁面中有require其它實現了,你還是能透過使用requirejs來使用requireJS API的(本文中沒有相關衝突,所以還是使用require)。

所以這意味著作為入門,你只需要掌握require,require.config,define這三樣就可以了。

本文将以介绍require,require.config,data-main,define的顺序来介绍RequireJS。让比较简单的RequireJS更加简单,争取让大家只看这篇文章就能用好RequireJS。至于RequireJS是如何解决循环依赖,对于没有实现amd的模块如何通过shim来导出,如何在node中使用等问题。本文并没有提及,详细有需要可以去官方查阅。

require.js可以通过npm下载或者在官网获得。jquery同理,jquery需要下载1.7.0或以上的版本。然后把对应的代码拷入对应的文件中,给出余下两个文件的代码:

//  js/script/index.html<!DOCTYPE html><html><head>
    <title>Require Demo 1</title></head><body>
    <div>
        <h1>Require Demo 1 -- usage of Require()</h1>
        <button id="contentBtn">Click me</button>
    <p id="messagebox"></p>
    </div>
    <script data-main="js/script/main" src="js/lib/require.js" type="text/javascript"></script> </body></html>      
    //  js/script/main.js
    require.config(
        {            paths: {                &#39;jquery&#39;: &#39;../lib/jquery-1.7.2&#39;
            }
        }
    );    require([&#39;jquery&#39;],function ($) {
             $(document).on(&#39;click&#39;,&#39;#contentBtn&#39;,function(){
                $(&#39;#messagebox&#39;).html(&#39;You have access Jquery by using require()&#39;);
             });
    });

先看index.html的代码,其实比较简单,页面上在js中会用到的就是一个button和一个p标签。然后整个页面就只是一个js文件是通过3f1c4e4b6b16bbbd69b2ee476dc4f83a标签加载的,就是require.js。注意到标签中有一个data-main属性,你现在只需要了解require.js会在加载完成以后通过回调方法去加载这个data-main里面的js文件,所以这个js文件被加载的时候,RequireJS已经加载执行完毕。

然后接着看main.js文件,里面被一个匿名立即执行函数所包括。在require.config(...)中,可以配置许多配置项,后面会有详细说明。上面在config中添加了一个path,在path配置了一个模块ID和路径的映射,这样在后续的所有函数中就可以直接通过模块ID来引入依赖,而不用再多次引入依赖多次输入路径带来的麻烦。

然后接着就是我们的require(...)函数了。上面的语法中require函数接受的第一个参数是,所依赖模块的一个数组。即使你只需要传入一个依赖,也需要把这个依赖放进数组中传入。如果你有如本例子中设置了模块ID和路径的映射,那你在传入依赖的时候就可以使用模块ID来代替路径,如果没有配置模块ID你当然也可以通过路径来引进对应的模块。接着是传入回调函数,当引入的依赖加载完毕后,这个回调函数就会被触发。如果你传入的依赖有注入变量(函数),然后在回调函数中需要用到,你就需要按照顺序在回调函数的参数中添加别名,在本例子中可以通过别名$来使用jQuery的相关API。所以有注入的模块需要放在无注入或者不需要调用模块的模块前面,方便回调函数传入别名。例子中在回调函数中为id为contentBtn的button注册监听事件,如果触发,则往id为messagebox的p标签添加相应的内容。

另外还需要额外说明的是路径,不管是在配置中写路径还是直接在require函数中写路径,你都需要了解requireJS在不同情况下的相对路径。

以下是相对路径的规则:

1.如果3f1c4e4b6b16bbbd69b2ee476dc4f83a标签引入require.js时没有指定data-main属性,则以引入该js的html文件所在的路径为根路径。

2.如果有指定data-main属性,也就是有指定入口文件,则以入口文件所在的路径为根路径。在本例子中也就是main.js所在的script文件夹就是根路径,这也是为什么配置jQuery的时候需要返回上层目录再进入lib目录才能找到jQuery文件。

3.如果再require.config()中有配置baseUrl,则以baseUrl的路径为根路径。
以上三条优先级逐级提升,如果有重叠,后面的根路径覆盖前面的根路径。

define

讲完了如何引入模块,现在讲如何定义一个模块,require定义一个模块是通过 define = function (name, deps, callback)完成的,第一个参数是定义模块名,第二个参数是传入定义模块所需要的依赖,第三个函数则是定义模块的主函数,主函数和require的回调函数一样,同样是在依赖加载完以后再调用执行。
先看个例子:

当你没有任何依赖的时候,你可以这么写:

//   js/script/desc.jsdefine(function(){    return{        decs : &#39;this js will be request only if it is needed&#39;,    };})      
//   然后在main.js的添加如下代码//   js/script/main.js
    $(&#39;#messagebox&#39;).html(&#39;You have access Jquery by using require()&#39;);
+  require([&#39;script/desc&#39;],function(desc){
+       alert(JSON.stringify(desc));

再次打开网页,打开network视图,点击按钮,通过require获得的desc模块就会alert出来,同时你会发现,desc.js是按需请求的,并不是在页面一开始的时候就请求的。

总结

以上就是关于关于RequireJS简单使用的介绍了,大家有需要可以直接看源码,大概就2000多行,不看具体实现,看它对几个函数声明的描述,对使用起来也是很有帮助的,你会发现有一些连官方文档都没提及到的一些特性(比如require()方法可以直接传入config配置作为第一个参数)。

另外,說一點小插曲,如果需要查閱RequireJS官方的API,有條件的還是建議直接訪問英文官方文件。如果說中文的官方文件說還停留在老版本,翻譯得比較生澀難懂就算了。有些很明顯有錯誤的描述就真的是責任問題了。我在看中文文檔的時候真是各種難移理解,後來直接看英文文檔,則順暢很多。

相信看了這些案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

相關閱讀:

用Video.js實作H5直播介面

JS程式碼怎麼實作記住帳號密碼

JavaScript基礎心法資料型別

以上是JS模組化-RequireJS的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn