requirejs加载顺序_前端模块化之AMD — Requirejs的使用
前言
隨著Ajax技術的興起,前后端分離的開發模式逐漸占領了幾乎整個市場,現在的服務器帶寬也足夠完成大量數據交互,于是很多以前在服務器端的邏輯也可以移植到前端來處理了,從而減輕服務器的壓力,當然,這樣的話Javascript代碼就會越來越復雜。而Javascript作為一門松散的弱類型語言,在一個大型項目面前如果沒有合理的拆分與規劃,將會變得很難維護,這個時候我們就需要把前端邏輯做一個模塊化的處理。
所謂模塊化就是把需要重復使用的功能封裝成模塊,一個頁面有一個統籌全局的對象把所有模塊引入進來,最終形成一個產品,做成一個完整的項目。
JS本身在ES6以前沒有模塊化的,ES6有模塊化了,但是主流瀏覽器對于ES6模塊化的支持度不足,所以一般不能直接使用,所以我們今天討論第三方的模塊化實現。
模塊化的好處
就好比要生產一臺挖掘機,是由各個廠商提供的配件組裝出來的,而不是由一家公司從頭到尾生產,這樣的好處是各個零部件各司其職,如果有一個功能壞掉了只需要找到對應的零部件解決問題即可,從而避免將來維修的麻煩。
作為代碼也是同樣的道理,一個完整的項目可以由很多個模塊組成,如果某部分功能需要修改或者升級只需要找到對應模塊的代碼進行維護即可,大大提高了代碼的可讀性以及節約了維護成本。
模塊化規范
模塊的使用一般分為導入和導出,定義一個模塊需要導出出去在需要使用的地方導入。所謂模塊化規范就是規定了模塊的使用方式,不同的規范制定了不同的導入和導出的方式。常見的模塊化規范有如下幾種:
AMD
依賴前置:提前引入,文件開頭把需要的模塊一次性全部引入,后面直接使用
前期消耗比較大,后期執行效率很高
代表作是 require.js
CMD
按需加載:在代碼執行過程當中需要一個模塊了才去加載
整個曲線比較平緩
代表作是sea.js,但是現在已經很少使用了
ES6 Module
瀏覽器都還不支持,但是可以借助像[webpack](https://www.webpackjs.com/ 'https://www.webpackjs.com/')這樣的打包工具來實現打包,從而使瀏覽器可以運行代碼。詳細用法可參照我的另一篇文章[鋒利的ES6 — Module](http://www.xiongdalin.com/2020/06/16/ES6-module/ 'http://www.xiongdalin.com/2020/06/16/ES6-module/') 。另外:服務器端Node.js遵循commonJS規范,module.exports 導出模塊,require引入模塊。
require.js
我們今天以require.js為例來說說前端模塊化的使用。
一、初探
第一步我們需要引入require.js文件
| 1 | <script src="https://requirejs.org/docs/release/2.3.6/minified/require.js">script> |
我們可以稍微查看一下文件的源代碼:
出乎我們意料的是require一上來二話不說先聲明了三個全局變量:require,requirejs以及define,但是這樣我們的方向也就很明確了,我們可以打印一下這三個值:
我們可以看到這是三個函數,而且require和requirejs看起來非常相似,所以我們可以嘗試打印一下:
| 1 | console.log(require === requirejs) // true |
這個結果毫無疑問是true,也就是說require和requirejs是同一個函數,那么我們肯定喜歡用require????
另外一個就是define,所以我們用requirejs其實用的就是require和define這兩個函數,而且結合咱們之前說過的模塊化就是定義模塊和使用模塊,所以define就是用來定義模塊而require是用來引入模塊的。
二、基本使用
比如我們定義一個a模塊,a.js的代碼可以如下:
| 123456789101112 | // module adefine(() => { class A { constructor (name) { this.name = name } say () { console.log(this.name) } } return A}) |
再定義一個b模塊,b.js代碼如下:
| 123456789101112 | // module bdefine(() => { class B { constructor () { this.name = 'module b' } say () { console.log(this.name) } } return new B()}) |
這里定義了一個類并分別return了這個類或者它的實例,這樣我們在需要的時候就可以在需要使用的頁面,比如與之同級的index.js中使用require函數來引入了:
| 12345 | require(['./a', './b'], (ModuleA, mB) => { console.log('index page code') new ModuleA('a').say() mB.say()}) |
我們通過require可以依次引入我們所需要的模塊,并且在回調函數里按順序接收各自模塊的返回值來使用,這樣就使得代碼可以非常方便的完成復用,實現模塊化了。
三、簡化
現在我們在頁面中需要寫兩個script標簽,一個用來引入require.js,另外一個用來引入當前頁面所需要的js,這樣還是比較麻煩,require.js給我們提供了更簡單的方式,我們可以在引入require.js的script中寫一個data-main屬性,如下:
| 1 | <script src="./js/require.min.js" data-main="./js/index">script> |
這樣就可以少寫一個script標簽,因為require.js會幫助我們找到當前script標簽上的自定義屬性data-main并且根據屬性值找到文件運行。
四、配置
現在模塊化已經具有一定規模了,但是在正式項目中文件路徑通常是比較復雜的,所以每次要依賴某個模塊都寫路徑的方式比較麻煩,因此我們可以將所有模塊做一個簡單的配置,我們可以新建一個config.js,假設我們的項目路徑如下:
在這個文件里我們可以集中將所有模塊以及其路徑做配置如下:
| 12345678 | require.config({ baseUrl: '/', // 當前項目跟路徑,可能需要視具體情況稍做調整 paths: { // 模塊名:'路徑' // 注意:路徑一定不能有后綴 a: 'js/a', b: 'js/b' }}) |
這樣我們可以修改一下index.js
| 1234567 | require(['./config'], () => { require(['a', 'b'], (ModuleA, mB) => { console.log('index page code') new ModuleA('a').say() mB.say() })}) |
這樣做的好處是現在引入模塊不用寫路徑了,而是直接使用在config.js里配置好的模塊名即可,簡單高效。
代碼不是萬能的,但不寫代碼是萬萬不能的
2020/07/13?Dary記
總結
以上是生活随笔為你收集整理的requirejs加载顺序_前端模块化之AMD — Requirejs的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何获取sharepoint列表_练习
- 下一篇: vscode放大缩小快捷键_浏览器使用指