js模塊規範cjs,js模塊規範esm

本文目錄一覽:

在node環境下怎麼使用commonjs模塊去使用require方法

最初的 CommonJS 小組 的參與者們決定弄一份於時下的 JavaScript 編程語言有效,但不必束縛於瀏覽器 JS 環境的限制,的模塊規範。開始的願景是在瀏覽器里使用一些權宜之計, 並希望能藉此影響瀏覽器廠商,促使它們為這種模塊規範的原生支持提供解決方案。權宜之計有:

要麼使用一個服務來轉譯 CJS 模塊成瀏覽器中可用的代碼

要麼使用 XMLHttpRequest(XHR)以文本形式載入模塊,再在瀏覽器中做文本變換、解析的工作

CJS 模塊規範僅允許每文件一個模塊,所以為優化、打包,可使用某種「轉換格式」將多個模塊合併到單個文件。

通過這種方式,CommonJS 小組搞定了依賴引用、如何處理循環依賴,以及如何獲得當前模塊的某些屬性等問題。 但是,他們並沒能接納瀏覽器環境里不可改變、並且仍將影響模塊設計的某些特性:

網路載入

非同步繼承 … 這也同時意味著他們為了實現這個規範,將負擔更多地放到了 Web 開發者身上,而這些權宜之計也使調試變得更麻煩。 調試 eval 的代碼,或者調試多個文件合併之後的單個文件,都有實際使用時的壞處。 這些缺點或許在未來某天會被瀏覽器調試工具解決掉,但結論仍然是:在最普遍的 JS 環境,瀏覽器中,使用 CommonJS 模塊並不是最好的辦法。

如何理解前端模塊化

前端模塊化

在JavaScript發展初期就是為了實現簡單的頁面交互邏輯,寥寥數語即可;如今CPU、瀏覽器性能得到了極大的提升,很多頁面邏輯遷移到了客戶端(表單驗證等),隨著web2.0時代的到來,Ajax技術得到廣泛應用,jQuery等前端庫層出不窮,前端代碼日益膨脹

這時候JavaScript作為嵌入式的腳本語言的定位動搖了,JavaScript卻沒有為組織代碼提供任何明顯幫助,甚至沒有類的概念,更不用說模塊(module)了,JavaScript極其簡單的代碼組織規範不足以駕馭如此龐大規模的代碼

模塊

既然JavaScript不能handle如此大規模的代碼,我們可以借鑒一下其它語言是怎麼處理大規模程序設計的,在Java中有一個重要帶概念——package,邏輯上相關的代碼組織到同一個包內,包內是一個相對獨立的王國,不用擔心命名衝突什麼的,那麼外部如果使用呢?直接import對應的package即可

import java.util.ArrayList;

遺憾的是JavaScript在設計時定位原因,沒有提供類似的功能,開發者需要模擬出類似的功能,來隔離、組織複雜的JavaScript代碼,我們稱為模塊化。

一個模塊就是實現特定功能的文件,有了模塊,我們就可以更方便地使用別人的代碼,想要什麼功能,就載入什麼模塊。模塊開發需要遵循一定的規範,各行其是就都亂套了

規範形成的過程是痛苦的,前端的先驅在刀耕火種、茹毛飲血的階段開始,發展到現在初具規模,簡單了解一下這段不凡的歷程

函數封裝

我們在講函數的時候提到,函數一個功能就是實現特定邏輯的一組語句打包,而且JavaScript的作用域就是基於函數的,所以把函數作為模塊化的第一步是很自然的事情,在一個文件裡面編寫幾個相關函數就是最開始的模塊了

function fn1(){

statement

}

function fn2(){

statement

}

這樣在需要的以後夾在函數所在文件,調用函數就可以了

這種做法的缺點很明顯:污染了全局變數,無法保證不與其他模塊發生變數名衝突,而且模塊成員之間沒什麼關係。

對象

為了解決上面問題,對象的寫法應運而生,可以把所有的模塊成員封裝在一個對象中

var myModule = {

var1: 1,

var2: 2,

fn1: function(){

},

fn2: function(){

}

}

這樣我們在希望調用模塊的時候引用對應文件,然後

myModule.fn2();

這樣避免了變數污染,只要保證模塊名唯一即可,同時同一模塊內的成員也有了關係

看似不錯的解決方案,但是也有缺陷,外部可以隨意修改內部成員

myModel.var1 = 100;

這樣就會產生意外的安全問題

立即執行函數

可以通過立即執行函數,來達到隱藏細節的目的

var myModule = (function(){

var var1 = 1;

var var2 = 2;

function fn1(){

}

function fn2(){

}

return {

fn1: fn1,

fn2: fn2

};

})();

這樣在模塊外部無法修改我們沒有暴露出來的變數、函數

上述做法就是我們模塊化的基礎,目前,通行的JavaScript模塊規範主要有兩種:CommonJS和AMD

CommonJS

我們先從CommonJS談起,因為在網頁端沒有模塊化編程只是頁面JavaScript邏輯複雜,但也可以工作下去,在伺服器端卻一定要有模塊,所以雖然JavaScript在web端發展這麼多年,第一個流行的模塊化規範卻由伺服器端的JavaScript應用帶來,CommonJS規範是由NodeJS發揚光大,這標誌著JavaScript模塊化編程正式登上舞台。

定義模塊

根據CommonJS規範,一個單獨的文件就是一個模塊。每一個模塊都是一個單獨的作用域,也就是說,在該模塊內部定義的變數,無法被其他模塊讀取,除非定義為global對象的屬性

模塊輸出:

模塊只有一個出口,module.exports對象,我們需要把模塊希望輸出的內容放入該對象

載入模塊:

載入模塊使用require方法,該方法讀取一個文件並執行,返迴文件內部的module.exports對象

js代碼規範問題 JavaScript判斷語句規範

規範性要參考幾個點:

1.是否影響效率

2.是否方便解讀

3.是否便於以後維護

針對這三點去做分析就行了,如樓上所說,沒有哪個人敢站出來說他寫的就是規範的,但是可以通過研究一些js庫去學習以形成習慣。

使用 MockJs — 實現真正的前後端分離

前言: 剛剛看了下的後台,發現我技術文章中,閱讀留言最多的是關於移動端的文章,甚至還有人付費讚賞或諮詢。關於 PC 端的技術文章就顯得比較冷清了,唉,廢了好大勁寫的,沒人看。 和我想的一樣,移動端才是王道,下次找工作我也搞移動端? 。

背景: 去年我寫了一篇 學習使用 json-server 和 mockjs 的文章,當時沒有仔細研究,文章只提到了 MockJs 其中一個 Random 的用法,關於 MockJs 攔截器和另一個很常用的 Mock.mock 函數都沒有提及。這次來搞一下。

唉!以前我也是經常會聽到 前後端分離 這個名詞,只模糊的知道它最重要的一個作用就是,大大的提升了 前端的地位。 但是平時在開發的時候,我也會想奶奶的,沒有介面這前端不就寫了一個破頁面,後期還的和後端對介面,對介面的時候花費的時間,肯定是不比前端開發的時候短,工期上最起碼一半一半吧, 這也就前後端分離 ,我這個小腦袋就不是太明白了。

不過我現在是終於搞明白這個問題了, 對於前端來講,真正的前後端分離,標誌是不依賴後端的前端工作開發完成,項目基本宣告結束。 後端開發完介面,只需要提換一個 URL 就行了,這也意味著前端需要去寫一些介面。

除了帶來開發任務稍微重點外,我至少看到了兩個最大的優點:

我體會最深就是這兩點。

插曲 :對了,今天中午我撿到一個手機,我必須要用一張動圖來描述下:

這個經典的 GIF ,來自鄭伊健的恐怖電影「第一誡」,清涼一冬,絕對值得一看,雖然劇情有很大的 bug ,但是港片就這點好,它有很抓人的地方,讓你覺得特別好看。

正文由此開始:

待續~~~

上面三種方案都可以,但你要知道介面很多,需要支持批量引入,所以 使用 Axios 響應攔截器 就不太可取,只能在這簡單的造些假數據。

著名開源項目 vue-element-admin 開發環境下模擬假介面使用的是 在 webpack-dev-server 的 before 處攔截。生產環境下是在項目入口文件( index,js )使用 Mock.mock 模擬的。

攔截請求的步驟如下,根據 devserverbefore 配置的栗子?:

可知道 before 接收一個函數,函數的第一個參數一般叫 app ,因為它的作用和 express 的 app 是等效的。也就是說這個 app 自帶路由, 正好解決介面批量引入的問題。

在項目中,一般都是這麼寫,把邏輯提出去:

./mock/mock-server.js 文件的內容為:

./mock/index.js 文件的內容為:

mockXHR 不用看,因為這是給線上環境用的,所以可以簡單的改寫為:

隨便找一個,例如 user 看下介面怎麼寫的:

完美,到此結束。

我想你一定對更改文件的時候,為什麼要 清路由和清緩存感興趣。

如果熟悉 express 框架,看到 app._router.stack 你就知道了。不知道也沒關,我演示給你看,新建一個JS 文件,文件內容為:

執行結束,看在 test.js 文件的內容:

發現沒,重複被添加的路由,不是覆蓋而是擴展。

這個涉及到 CJS 模塊的運行機制, 記住 require 的文件會被加到 require.cache 裡面,當文件改變讀的是緩存,而不是最新更改的文件。

項目結構過大,如果只在 mock 文件夾裡面管理有點麻煩,我就想在頁面所在目錄直接寫介面,怎麼辦?沒錯使用 require.context 來批量引入。但是 NodeJs 是沒有批量引入的 API 的。找遍了 npm 也沒發現一個 package 和 require.context 長得像的。

難道沒辦法了嗎?當然不是,自己動手豐衣足食。 依照 vue-cli 插件的命名規範,我給寫的 package 取名 node-plugin-require-context ,簡單講下實現原理:

其實還有一個缺點,如果你看過 Antd-Pro 項目,你就會發現它模擬數據,模塊化採用的是 ESModule ,而不是 CJS。保持編碼模塊化風格一致確實也是需要優化的一個地方,不管了,反正我不幹。

官網本來就是中文的,我在使用中發現寫的賊好,我就不用畫蛇添足了。建議每次使用前:

如何在html和JS中包含Javascript JS文件終極解決方案

現在常用的一種javascript的方法是在當前的html文檔中插入一個script標籤,在標籤中引入script腳本Js代碼var__includes__=newArray;Array.prototype.indexOf=function(obj){for(vari=0;ithis.length;i++){if(this[i]==obj)returni;}return-1;}Array.prototype.add=function(obj){this[this.length]=obj;}functioninclude_js(js){if(__includes__.indexOf(js)-1)return;__includes__.add(js);varhead=document.getElementsByTagName(‘head’)[0];script=document.createElement(‘script’);script.src=js;script.type=’text/javascript’;head.appendChild(script);}當你只是在你的htmlw文檔中使用這個方法的時候,一切OK,這其實是script的標籤的一種快捷的寫法而已。但是,如果你在一個javascript使用這個方法,問題就來了,比如我在test.js中使用include_js(“test1.js”),在test1.js中有一個變數test1是在test.js中要使用的,在webkit中盡然出現了test1變數未定義的錯誤,我不知道ie和firefox是否有這種問題,我想可能是include_js本身不是同步執行導致的,所以我只好使用以下方法來完善inlcude_jsJs代碼var__includes__=newArray;Array.prototype.indexOf=function(obj){for(vari=0;ithis.length;i++){if(this[i]==obj)returni;}return-1;}Array.prototype.add=function(obj){this[this.length]=obj;}functionxhttp(url,callback){varrequest=null;if(typeofXMLHttpRequest!=’undefined’){request=newXMLHttpRequest();}elseif(typeofActiveXObject!=’undefined’){request=newActiveXObject(‘Microsoft.XMLHTTP’);}request.open(‘GET’,url,true);request.onreadystatechange=function(){if(request.readyState==4){callback(request.responseText);}};request.send(null);}functionadd_scripts(jss,callback){varfunc=function(jss,idx,callback){if(idx==jss.length){callback();return};add_script(jss[idx],function(){func(jss,++idx,callback);});}func(jss,0,callback);}functionadd_script(js,callback){if(__includes__.indexOf(js)-1){callback();return;}__includes__.add(js);xhttp(js,function(js_content){varhead=document.getElementsByTagName(‘head’)[0];script=document.createElement(‘script’);head.appendChild(script);// script.innerHTML=js_content; //原帖是這個…本人測試這行..無效 必須用text屬性賦值script.defer=true; script.type=’text/javascript’;script.language=’javascript’;//本人測試修正..添加script.text=js_content;//本人測試修正..添加//zfrong 09.5.20callback();});}functioninclude_js(js){if(__includes__.indexOf(js)-1)return;__includes__.add(js);varhead=document.getElementsByTagName(‘head’)[0];script=document.createElement(‘script’);script.src=js;script.type=’text/javascript’;head.appendChild(script);}當我在html文檔中引入的時候,我用 include_js,當我在js文件中引入js時候,我使用add_scripts,add_scriptJs代碼add_scripts([‘test1.js’,’test2.js’]),add_scripts方法使用了xmlhttp來讀入js內容,並把讀入的內容的寫到一個新的script標籤內,讀入是非同步執行的,當執行完畢後,會調用callback、

原創文章,作者:XBCI,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/133934.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
XBCI的頭像XBCI
上一篇 2024-10-04 00:02
下一篇 2024-10-04 00:02

相關推薦

發表回復

登錄後才能評論