模塊化這個(gè)問(wèn)題并非一開始就存在,WWW剛剛問(wèn)世的時(shí)候,html,JavaScript,CSS(JS和CSS都是后來(lái)在網(wǎng)景被引進(jìn)瀏覽器的)都是極其簡(jiǎn)單的存在,不需要模塊化。
創(chuàng)新互聯(lián)是專業(yè)的廣饒網(wǎng)站建設(shè)公司,廣饒接單;提供網(wǎng)站設(shè)計(jì)、做網(wǎng)站,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行廣饒網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
模塊化的需求是規(guī)模的產(chǎn)物,當(dāng)web page進(jìn)化到web application,瀏覽器端處理的邏輯越來(lái)越復(fù)雜,展現(xiàn)的樣式和動(dòng)畫越來(lái)多,對(duì)于工程的要求也就越來(lái)越高。于是模塊化的需求也就產(chǎn)生了。模塊化的意義:
JavaScript長(zhǎng)久以來(lái)被認(rèn)為是簡(jiǎn)單的腳本語(yǔ)言,實(shí)際上情況早就發(fā)生來(lái)變化,在最新版的JavaScript是通用編程語(yǔ)言而不是腳本語(yǔ)言。腳本語(yǔ)言,比如shell并不是用來(lái)完成復(fù)雜功能的,只是用來(lái)做一些自動(dòng)化控制,是不需要模塊化的。而用于構(gòu)建復(fù)雜系統(tǒng)通用編程語(yǔ)言(比如Java)一般都有模塊的實(shí)現(xiàn)。
ES6之前,JavaScript并沒有原生的模塊機(jī)制,好在JavaScript非常靈活,有很多種寫法可以將代碼天然隔離,起到模塊化的功能:
//define
var modules = {}??
modules.mod1 = {??
??foo : function(){...},
??bar : function(){...}
??...
} //歡迎加入前端全棧開發(fā)交流圈一起學(xué)習(xí)交流:1007317281
//call
modules.mod1.foo()
在客戶端這種方式基本是夠用的,然而問(wèn)題依然存在:你無(wú)法管理依賴,所有的代碼都必須load到內(nèi)存中,需要哪些模塊必須由人工處理。分模塊是工程化的產(chǎn)物,也是自然發(fā)展的結(jié)果,自然有很多嘗試。很顯然,模塊之間互相依賴需要編寫模塊的時(shí)候遵循一定的規(guī)范?,F(xiàn)存的規(guī)范還真不少,不知道ES6 能否終結(jié)這場(chǎng)混戰(zhàn):
AMD和CMD分別是requireJS和seaJS定義的標(biāo)準(zhǔn)。使用純?cè)腅S5語(yǔ)法意味者其只能使用閉包,書寫和閱讀都很怪異。值得一提的是AngularJS也使用類似的方式,以至于Angular的作者們都受不了,決定在AngularJS 2 使用新的語(yǔ)言AtScript,前端輪子太多,又造了一個(gè),好在這個(gè)輪子造的比較好,兼容ES6 TypeScript規(guī)范,扯的遠(yuǎn)了,看看AMD長(zhǎng)得啥樣:
AMD:
define(['./a', './b'], function(a, b) {??
??...
})
Closure是google出品的前端工具,Closure提供了一系列工具和庫(kù),谷歌自己的多個(gè)項(xiàng)目都是使用Closure開發(fā)的。closure compiler通過(guò)模塊間依賴的聲明把所有被依賴的文件打包到一起,而且Closure的一大優(yōu)勢(shì)是如果采用破壞性壓縮(ADVANCED)壓縮率極高。
//文件A
goog.provide('module1')??
com.foo.bar = {??
...
} //歡迎加入前端全棧開發(fā)交流圈一起學(xué)習(xí)交流:1007317281
//文件B
goog.require('module1')??
var a = com.foo.bar;
然而Closure并不完美,不同的文件共享同一個(gè)全局對(duì)象,所以你不得不這樣寫 a.b.c=...。
CommonJS是Node.js使用的模塊化標(biāo)準(zhǔn)。Node.js對(duì)于前端開發(fā)者來(lái)說(shuō)不僅僅可以提供一個(gè)Server,還是一個(gè)完美的開發(fā)平臺(tái),在Node上使用Grunt/gulp構(gòu)建web項(xiàng)目是件很爽的事情。Node的模塊化聲明的方式與Closure類似,只是更進(jìn)一步,天然隔離了命名空間。上面的代碼如果使用CommonJS的模塊化規(guī)范可以這么寫
//文件A
module.exports = {...}??
//文件B
var a = require('./foo/bar')
browserify讓使用CommonJS模塊化規(guī)范的代碼可以運(yùn)行在客戶端上。
在看ES6之前我們先看模塊加載的兩種方式:
AMD標(biāo)準(zhǔn)是動(dòng)態(tài)加載的代表,而CommonJS是靜態(tài)加載的代表。AMD的目的是用在瀏覽器上,所以是異步加載的。而NodeJS是運(yùn)行在服務(wù)器上的,同步加載的方式顯然更容易被人接收,所以使用了CommonJS。同樣的道理,如果靜態(tài)加載,那就使用同步的加載方式,如果動(dòng)態(tài)加載就必須用異步的加載方式。
那么ES6采用何種加載機(jī)制?
ES6既希望用簡(jiǎn)單的聲明方式來(lái)完成靜態(tài)加載,又不愿放棄動(dòng)態(tài)加載的特性,而這兩種方式幾乎不可能簡(jiǎn)單的同時(shí)實(shí)現(xiàn),所以ES6提供了兩種獨(dú)立的模塊加載方法。
2.1 聲明的方式
import {foo} from module1
2.2 通過(guò)System.import API的方式
System.import('some_module')??
????.then(some_module => {
????????// Use some_module
????})
????.catch(error => {
????????...
????}); //歡迎加入前端全棧開發(fā)交流圈一起學(xué)習(xí)交流:1007317281
再看下export的語(yǔ)法,與CommonJS很像,只不過(guò)沒有了module這個(gè)對(duì)象,而直接調(diào)用export。 可以export任何一個(gè) 函數(shù),變量,對(duì)象
//expt.js
export function abc(){}//export 一個(gè)命名的function??
export default function(){} //export default function??
export num=123 //export 一個(gè)數(shù)值??
export obj={}??
export { obj as default };
//import
import expt from 'expt'//default export??
import {default as myModule} from 'expt' //rename??
import {abc,num,obj} from 'expt'
目前來(lái)看,使用預(yù)編譯的方式顯然要好于使用動(dòng)態(tài)加載,瀏覽器對(duì)ES6語(yǔ)法支持還很差,如果使用動(dòng)態(tài)加載ES6,在瀏覽器端要做ES6到ES5的翻譯工作,這個(gè)顯然是重復(fù)低效的。但是隨著瀏覽器對(duì)ES6支持增強(qiáng),尤其是瀏覽器實(shí)現(xiàn)了動(dòng)態(tài)加載API后,動(dòng)態(tài)加載的優(yōu)勢(shì)就會(huì)展現(xiàn):
如果現(xiàn)在使用ES6,可以選擇動(dòng)態(tài)加載模塊system.js 或者browserify的預(yù)編譯方法。
使用system.js+babel動(dòng)態(tài)加載依賴。system.js 是ES6動(dòng)態(tài)模塊加載的一個(gè)實(shí)現(xiàn)。寫了一個(gè)小DEMO:
項(xiàng)目初始化
bower install babel system.js --save
index.html
????<script src="/bower_components/system.js/dist/system.js"></script>
????<script>
??????System.config({
??????????baseURL : "/scripts",
??????????transpiler : 'babel',
??????????map : {
????????????babel:'/bower_components/babel/browser.js'
??????????}
????????} //歡迎加入前端全棧開發(fā)交流圈一起學(xué)習(xí)交流:1007317281
??????)
??????System.import('main.js').then(function(m){
????????m.default.sayHello()
??????})
????</script>
main.js
export default {??
??sayHello : function(){
????console.log('hello')
??}
}
使用gulp+browserify+babel預(yù)編譯。gulp是一個(gè)Node.js平臺(tái)上的任務(wù)管理平臺(tái)。預(yù)編譯要做很多配置,非常繁瑣,推薦使用yeoman來(lái)生成項(xiàng)目骨架。比如使用generator-es6-webapp。
生成非常簡(jiǎn)單,在項(xiàng)目目錄中執(zhí)行
yo es6-webapp
缺少依賴的化安裝依賴就好。
ES6模塊化意味著什么?
更強(qiáng)大的前端,Web技術(shù)整體前移。HTML5的發(fā)展和某些優(yōu)秀瀏覽器的支持讓web技術(shù)整體前移,以前像渲染這種工作在后端進(jìn)行是由于瀏覽器薄弱,且有老IE這種拖后腿搗亂的選手。
簡(jiǎn)化編程模型,人工管理JS依賴和將多個(gè)JS打包這種工作可以不需要了,而配合WebComponents標(biāo)準(zhǔn),開發(fā)Web將不再借助模板引擎和預(yù)編譯引擎。
前端化還有更深遠(yuǎn)的影響--在過(guò)去瀏覽器是個(gè)工具,現(xiàn)在瀏覽器是個(gè)重要的工具,在未來(lái)瀏覽器就是用戶唯一的操作系統(tǒng)。
感謝您的觀看,如有不足之處,歡迎批評(píng)指正。
**獲取前端資料
當(dāng)前文章:寫了十年JS卻不知道模塊化為何物?
分享URL:http://muchs.cn/article4/ijsioe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、Google、品牌網(wǎng)站制作、服務(wù)器托管、小程序開發(fā)、微信公眾號(hào)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)