摘要:本文首發(fā)于的技術(shù)博客實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。怎么來(lái)兼容老式插件呢方法有不少,下面一個(gè)一個(gè)來(lái)看。與上述的方案相反,此方案是先用加載的滿(mǎn)足老式插件的需要,再通過(guò)將其轉(zhuǎn)換成符合模塊化要求的。
本文首發(fā)于Array_Huang的技術(shù)博客——實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。前言
原文地址:https://segmentfault.com/a/1190000006887523
如果您對(duì)本系列文章感興趣,歡迎關(guān)注訂閱這里:https://segmentfault.com/blog/array_huang
目前前端雖處于百花齊放階段,angular/react/vue競(jìng)相角逐,但畢竟尚未完全成熟,有些需求還是得依靠我們的老大哥jQuery的。
我個(gè)人對(duì)jQuery并不反感,但我對(duì)jQuery生態(tài)的停滯不前相當(dāng)無(wú)奈,比如說(shuō)赫赫有名的bootstrap(特指3代),在webpack上打包還得靠個(gè)loader的,太跟不上時(shí)勢(shì)了。況且,bootstrap還算好的,有些jquery插件都有一兩年沒(méi)更新了,連NPM都沒(méi)上架呢,可偏偏就是找不到它們的替代品,項(xiàng)目又急著要上,這可咋辦吶?
別急,今天就教你適配兼容老式j(luò)Query插件。
老式j(luò)Query插件為和不能直接用webpack打包?如果你把jQuery看做是一個(gè)普通的js模塊來(lái)加載(要用到j(luò)Query的模塊統(tǒng)統(tǒng)先require后再使用),那么,當(dāng)你加載老式j(luò)Query插件時(shí),往往會(huì)提示找不到j(luò)Query實(shí)例(有時(shí)候是提示找不到$),這是為啥呢?
要解釋這個(gè)問(wèn)題,就必須先稍微解釋一下jQuery插件的機(jī)制:jQuery插件是通過(guò)jQuery提供的jQuery.fn.extend(object)和jQuery.extend(object)這倆方法,來(lái)把插件本身實(shí)現(xiàn)的方法掛載到jQuery(也即$)這個(gè)對(duì)象上的。傳統(tǒng)引用jQuery及其插件的方式是先用加載jQuery本身,然后再用同樣的方法來(lái)加載其插件;jQuery會(huì)把jQuery對(duì)象設(shè)置為全局變量(當(dāng)然也包括了$),既然是全局變量,那么插件們很容易就能找到jQuery對(duì)象并掛載自身的方法了。
而webpack作為一個(gè)遵從模塊化原則的構(gòu)建工具,自然是要把各模塊的上下文環(huán)境給分隔開(kāi)以減少相互間的影響;而jQuery也早已適配了AMD/CMD等加載方式,換句話(huà)說(shuō),我們?cè)趓equire jQuery的時(shí)候,實(shí)際上并不會(huì)把jQuery對(duì)象設(shè)置為全局變量。說(shuō)到這里,問(wèn)題也很明顯了,jQuery插件們找不到jQuery對(duì)象了,因?yàn)樵谒鼈兏髯缘纳舷挛沫h(huán)境里,既沒(méi)有局部變量jQuery(因?yàn)闆](méi)有適配AMD/CMD,所以就沒(méi)有相應(yīng)的require語(yǔ)句了),也沒(méi)有全局變量jQuery。
怎么來(lái)兼容老式j(luò)Query插件呢?方法有不少,下面一個(gè)一個(gè)來(lái)看。
ProvidePlugin + expose-loader首先來(lái)介紹我最為推薦的方法:ProvidePlugin + expose-loader,在我公司的項(xiàng)目,以及我個(gè)人的腳手架開(kāi)源項(xiàng)目webpack-seed里使用的都是這一種方法。
ProvidePlugin的配置是這樣的:
var providePlugin = new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery", "window.$": "jquery", });
ProvidePlugin的機(jī)制是:當(dāng)webpack加載到某個(gè)js模塊里,出現(xiàn)了未定義且名稱(chēng)符合(字符串完全匹配)配置中key的變量時(shí),會(huì)自動(dòng)require配置中value所指定的js模塊。
如上述例子,當(dāng)某個(gè)老式插件使用了jQuery.fn.extend(object),那么webpack就會(huì)自動(dòng)引入jquery(此處我是用NPM的版本,我也推薦使用NPM的版本)。
另外,使用ProvidePlugin還有個(gè)好處,就是,你自己寫(xiě)的代碼里,再!也!不!用!require!jQuery!啦!畢竟少寫(xiě)一句是一句嘛哈哈哈。
接下來(lái)介紹expose-loader,這個(gè)loader的作用是,將指定js模塊export的變量聲明為全局變量。下面來(lái)看下expose-loader的配置:
/* 很明顯這是一個(gè)loader的配置項(xiàng),篇幅有限也只能截取相關(guān)部分了 看不明白的麻煩去看本系列的另一篇文章《webpack多頁(yè)應(yīng)用架構(gòu)系列(二):webpack配置常用部分有哪些?》:https://segmentfault.com/a/1190000006863968 */ { test: require.resolve("jquery"), // 此loader配置項(xiàng)的目標(biāo)是NPM中的jquery loader: "expose?$!expose?jQuery", // 先把jQuery對(duì)象聲明成為全局變量`jQuery`,再通過(guò)管道進(jìn)一步又聲明成為全局變量`$` },
你或許會(huì)問(wèn),有了ProvidePlugin為嘛還需要expose-loader?問(wèn)得好,如果你所有的jQuery插件都是用webpack來(lái)加載的話(huà),的確用ProvidePlugin就足夠了;但理想是豐滿(mǎn)的,現(xiàn)實(shí)卻是骨感的,總有那么些需求是只能用來(lái)加載的。
externalsexternals是webpack配置中的一項(xiàng),用來(lái)將某個(gè)全局變量“偽裝”成某個(gè)js模塊的exports,如下面這個(gè)配置:
externals: { "jquery": "window.jQuery", },
那么,當(dāng)某個(gè)js模塊顯式地調(diào)用var $ = require("jquery")的時(shí)候,就會(huì)把window,jQuery返回給它。
與上述ProvidePlugin + expose-loader的方案相反,此方案是先用加載的jQuery滿(mǎn)足老式j(luò)Query插件的需要,再通過(guò)externals將其轉(zhuǎn)換成符合模塊化要求的exports。
我個(gè)人并不太看好這種做法,畢竟這就意味著jQuery脫離NPM的管理了,不過(guò)某些童鞋有其它的考慮,例如為了加快每次打包的時(shí)間而把jQuery這些比較大的第三方庫(kù)給分離出去(直接調(diào)用公共CDN的第三方庫(kù)?),也算是有一定的價(jià)值。
imports-loader這個(gè)方案就相當(dāng)于手動(dòng)版的ProvidePlugin,以前我用requireJS的時(shí)候也是用的類(lèi)似的手段,所以我一開(kāi)始從requireJS遷移到webpack的時(shí)候用的也是這種方法,后來(lái)知道有ProvidePlugin就馬上換了哈。
這里就不詳細(xì)說(shuō)明了,放個(gè)例子大家看看就懂:
// ./webpack.config.js module.exports = { ... module: { loaders: [ { test: require.resolve("some-module"), loader: "imports?$=jquery&jQuery=jquery", // 相當(dāng)于`var $ = require("jquery");var jQuery = require("jquery");` } ] } };總結(jié)
以上的方案其實(shí)都屬于shimming,并不特別針對(duì)jQuery,請(qǐng)舉一反三使用。另外,上述方案并不僅用于shimming,比如用上ProvidePlugin來(lái)寫(xiě)少幾個(gè)require,自己多多挖掘,很有樂(lè)趣的哈~~
補(bǔ)充 誤用externals(2016-10-17更新)有童鞋私信我,說(shuō)用了我文章的方案依然提示$ is not a function,在我仔細(xì)分析后,發(fā)現(xiàn):
他用的是我推薦的ProvidePlugin + expose-loader方案,也就是說(shuō),他已經(jīng)把jquery打包進(jìn)來(lái)了。
但是他又不明就里得配了externals:
externals: { jquery: "window.jQuery", },
然而實(shí)際上他并沒(méi)有直接用來(lái)引用jQuery,因此window.jQuery是個(gè)null。
結(jié)果,他的jquery插件獲得的$就是個(gè)null了。
這里面我們可以看出,externals是會(huì)覆蓋掉ProvidePlugin的。
但這里有個(gè)問(wèn)題,expose-loader的作用就是設(shè)置好window.jQuery和window.$,那window.jQuery怎么會(huì)是null呢?我的猜想是:externals在expose-loader設(shè)置好window.jQuery前就已經(jīng)取了window.jQuery的值(null)了。
說(shuō)了這么多,其實(shí)關(guān)鍵意思就是,不要手賤不要手賤不要手賤(重要的事情說(shuō)三遍)!
示例代碼諸位看本系列文章,搭配我在Github上的腳手架項(xiàng)目食用更佳哦(笑):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed)。
附系列文章目錄(同步更新)webpack多頁(yè)應(yīng)用架構(gòu)系列(一):一步一步解決架構(gòu)痛點(diǎn):https://segmentfault.com/a/1190000006843916
webpack多頁(yè)應(yīng)用架構(gòu)系列(二):webpack配置常用部分有哪些?:https://segmentfault.com/a/1190000006863968
webpack多頁(yè)應(yīng)用架構(gòu)系列(三):怎么打包公共代碼才能避免重復(fù)?:https://segmentfault.com/a/1190000006871991
webpack多頁(yè)應(yīng)用架構(gòu)系列(四):老式j(luò)Query插件還不能丟,怎么兼容?:https://segmentfault.com/a/1190000006887523
webpack多頁(yè)應(yīng)用架構(gòu)系列(五):聽(tīng)說(shuō)webpack連less/css也能打包?:https://segmentfault.com/a/1190000006897458
webpack多頁(yè)應(yīng)用架構(gòu)系列(六):聽(tīng)說(shuō)webpack連圖片和字體也能打包?:https://segmentfault.com/a/1190000006907701
webpack多頁(yè)應(yīng)用架構(gòu)系列(七):開(kāi)發(fā)環(huán)境、生產(chǎn)環(huán)境傻傻分不清楚?:https://segmentfault.com/a/1190000006952432
webpack多頁(yè)應(yīng)用架構(gòu)系列(八):教練我要寫(xiě)ES6!webpack怎么整合Babel?:https://segmentfault.com/a/1190000006992218
webpack多頁(yè)應(yīng)用架構(gòu)系列(九):總有刁民想害朕!ESLint為你阻擊垃圾代碼:https://segmentfault.com/a/1190000007030775
webpack多頁(yè)應(yīng)用架構(gòu)系列(十):如何打造一個(gè)自定義的bootstrap:https://segmentfault.com/a/1190000007043716
webpack多頁(yè)應(yīng)用架構(gòu)系列(十一):預(yù)打包Dll,實(shí)現(xiàn)webpack音速編譯:https://segmentfault.com/a/1190000007104372
webpack多頁(yè)應(yīng)用架構(gòu)系列(十二):利用webpack生成HTML普通網(wǎng)頁(yè)&頁(yè)面模板:https://segmentfault.com/a/1190000007126268
webpack多頁(yè)應(yīng)用架構(gòu)系列(十三):構(gòu)建一個(gè)簡(jiǎn)單的模板布局系統(tǒng):https://segmentfault.com/a/1190000007159115
webpack多頁(yè)應(yīng)用架構(gòu)系列(十四):No復(fù)制粘貼!多項(xiàng)目共用基礎(chǔ)設(shè)施
webpack多頁(yè)應(yīng)用架構(gòu)系列(十五):論前端如何在后端渲染開(kāi)發(fā)模式下夾縫生存
webpack多頁(yè)應(yīng)用架構(gòu)系列(十六):善用瀏覽器緩存,該去則去,該留則留
本文首發(fā)于Array_Huang的技術(shù)博客——實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。
原文地址:https://segmentfault.com/a/1190000006887523
如果您對(duì)本系列文章感興趣,歡迎關(guān)注訂閱這里:https://segmentfault.com/blog/array_huang
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90987.html
摘要:我個(gè)人慣用的是,因此本文以為例來(lái)介紹如何打造一個(gè)自定義的。引入全局的方法請(qǐng)看我之前的這篇文章多頁(yè)應(yīng)用架構(gòu)系列四老式插件還不能丟,怎么兼容,我的腳手架項(xiàng)目也是使用的這套方案。 本文首發(fā)于Array_Huang的技術(shù)博客——實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/1190000007043716如果您對(duì)本系列文章感興趣,歡迎關(guān)注訂閱...
摘要:本文首發(fā)于的技術(shù)博客實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。原文地址如果您對(duì)本系列文章感興趣,歡迎關(guān)注訂閱這里這系列文章講什么本系列文章主要介紹如何用這一當(dāng)前流行的構(gòu)建工具來(lái)設(shè)計(jì)一個(gè)多頁(yè)應(yīng)用的架構(gòu)。 本文首發(fā)于Array_Huang的技術(shù)博客——實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/1190000006843916如果您對(duì)本系列文章...
摘要:本文首發(fā)于的技術(shù)博客實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。原文地址如果您對(duì)本系列文章感興趣,歡迎關(guān)注訂閱這里前言書(shū)承上文多頁(yè)應(yīng)用架構(gòu)系列十如何打造一個(gè)自定義的。終于,發(fā)現(xiàn)了這一大殺器,打包時(shí)間過(guò)長(zhǎng)的問(wèn)題得到完美解決。 本文首發(fā)于Array_Huang的技術(shù)博客——實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/119000000710437...
摘要:本文首發(fā)于的技術(shù)博客實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。如果你使用了,或類(lèi)似的,那么,通過(guò)編譯前后的代碼相差就很大了,這會(huì)造成兩個(gè)問(wèn)題以為例把你的代碼轉(zhuǎn)成什么樣你自己是無(wú)法控制的,這往往導(dǎo)致無(wú)法通過(guò)的審查。 本文首發(fā)于Array_Huang的技術(shù)博客——實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/1190000007030775如果您...
摘要:在上一篇文章多頁(yè)應(yīng)用架構(gòu)系列二配置常用部分有哪些中,我介紹了如何配置多頁(yè)應(yīng)用的入口,然而,如果僅僅如此操作,帶來(lái)的后果就是,打包生成出來(lái)的每一個(gè)入口文件都會(huì)完整包含所有代碼。的初始化常用參數(shù)有哪些,給這個(gè)包含公共代碼的命個(gè)名唯一標(biāo)識(shí)。 本文首發(fā)于Array_Huang的技術(shù)博客——實(shí)用至上,非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/1190...
閱讀 1460·2021-11-22 14:44
閱讀 2843·2021-11-16 11:44
閱讀 3206·2021-10-13 09:40
閱讀 1980·2021-10-08 10:04
閱讀 2363·2021-09-24 10:28
閱讀 2909·2021-09-06 15:02
閱讀 2957·2019-08-30 15:52
閱讀 2392·2019-08-30 13:20