摘要:相關(guān)的內(nèi)容為這樣對(duì)于一個(gè)處理的第二階段也就結(jié)束了,通過(guò)去攔截不同類(lèi)型的,并返回新的,跳過(guò)后面的的執(zhí)行,同時(shí)在內(nèi)部會(huì)剔除掉,這樣在進(jìn)入到下一個(gè)處理階段的時(shí)候,不在使用的范圍之內(nèi),因此下一階段便不會(huì)經(jīng)由來(lái)處理。
文章首發(fā)于個(gè)人github blog: Biu-blog,歡迎大家關(guān)注~
Webpack 系列文章:
Webpack Loader 高手進(jìn)階(一)
Webpack Loader 高手進(jìn)階(二)
Webpack Loader 高手進(jìn)階(三)
前2篇文章主要通過(guò)源碼分析了 loader 的配置,匹配和加載,執(zhí)行等內(nèi)容,這篇文章會(huì)通過(guò)具體的實(shí)例來(lái)學(xué)習(xí)下如何去實(shí)現(xiàn)一個(gè) loader。
這里我們來(lái)看下 vue-loader(v15) 內(nèi)部的相關(guān)內(nèi)容,這里會(huì)講解下有關(guān) vue-loader 的大致處理流程,不會(huì)深入特別細(xì)節(jié)的地方。
git clone git@github.com:vuejs/vue-loader.git
我們使用 vue-loader 官方倉(cāng)庫(kù)當(dāng)中的 example 目錄的內(nèi)容作為整篇文章的示例。
首先我們都知道 vue-loader 配合 webpack 給我們開(kāi)發(fā) Vue 應(yīng)用提供了非常大的便利性,允許我們?cè)?SFC(single file component) 中去寫(xiě)我們的 template/script/style,同時(shí) v15 版本的 vue-loader 還允許開(kāi)發(fā)在 SFC 當(dāng)中寫(xiě) custom block。最終一個(gè) Vue SFC 通過(guò) vue-loader 的處理,會(huì)將 template/script/style/custom block 拆解為獨(dú)立的 block,每個(gè) block 還可以再交給對(duì)應(yīng)的 loader 去做進(jìn)一步的處理,例如你的 template 是使用 pug 來(lái)書(shū)寫(xiě)的,那么首先使用 vue-loader 獲取一個(gè) SFC 內(nèi)部 pug 模板的內(nèi)容,然后再交給 pug 相關(guān)的 loader 處理,可以說(shuō) vue-loader 對(duì)于 Vue SFC 來(lái)說(shuō)是一個(gè)入口處理器。
在實(shí)際運(yùn)用過(guò)程中,我們先來(lái)看下有關(guān) Vue 的 webpack 配置:
const VueloaderPlugin = require("vue-loader/lib/plugin") module.exports = { ... module: { rules: [ ... { test: /.vue$/, loader: "vue-loader" } ] } plugins: [ new VueloaderPlugin() ] ... }
一個(gè)就是 module.rules 有關(guān)的配置,如果處理的 module 路徑是以.vue形式結(jié)尾的,那么會(huì)交給 vue-loader 來(lái)處理,同時(shí)在 v15 版本必須要使用 vue-loader 內(nèi)部提供的一個(gè) plugin,它的職責(zé)是將你定義過(guò)的其它規(guī)則復(fù)制并應(yīng)用到 .vue 文件里相應(yīng)語(yǔ)言的塊。例如,如果你有一條匹配 /.js$/ 的規(guī)則,那么它會(huì)應(yīng)用到 .vue 文件里的
template block 會(huì)經(jīng)過(guò)以下的流程處理:
source.vue?vue&type=template -> vue-loader(抽離 template block ) -> pug-plain-loader(將 pug 模塊轉(zhuǎn)化為 html 字符串) -> templateLoader(編譯 html 模板字符串,生成 render/staticRenderFns 函數(shù)并暴露出去)
我們看到經(jīng)過(guò) vue-loader 處理時(shí),會(huì)根據(jù)不同 module path 的類(lèi)型(query 參數(shù)上的 type 字段)來(lái)抽離 SFC 當(dāng)中不同類(lèi)型的 block。這也是 vue-loader 內(nèi)部定義的相關(guān)規(guī)則:
// vue-loader/lib/index.js const qs = require("querystring") const selectBlock = require("./select") ... module.exports = function (source) { ... const rawQuery = resourceQuery.slice(1) const inheritQuery = `&${rawQuery}` const incomingQuery = qs.parse(rawQuery) ... const descriptor = parse({ source, compiler: options.compiler || loadTemplateCompiler(), filename, sourceRoot, needMap: sourceMap }) // if the query has a type field, this is a language block request // e.g. foo.vue?type=template&id=xxxxx // and we will return early if (incomingQuery.type) { return selectBlock( descriptor, loaderContext, incomingQuery, !!options.appendExtension ) } ... }
當(dāng) module path 上的 query 參數(shù)帶有 type 字段,那么會(huì)直接調(diào)用 selectBlock 方法去獲取 type 對(duì)應(yīng)類(lèi)型的 block 內(nèi)容,跳過(guò) vue-loader 后面的處理流程(這也是與 vue-loader 第一次處理這個(gè) module時(shí)流程不一樣的地方),并進(jìn)入到下一個(gè) loader 的處理流程中,selectBlock 方法內(nèi)部主要就是根據(jù)不同的 type 類(lèi)型(template/script/style/custom),來(lái)獲取 descriptor 上對(duì)應(yīng)類(lèi)型的 content 內(nèi)容并傳入到下一個(gè) loader 處理:
module.exports = function selectBlock ( descriptor, loaderContext, query, appendExtension ) { // template if (query.type === `template`) { if (appendExtension) { loaderContext.resourcePath += "." + (descriptor.template.lang || "html") } loaderContext.callback( null, descriptor.template.content, descriptor.template.map ) return } // script if (query.type === `script`) { if (appendExtension) { loaderContext.resourcePath += "." + (descriptor.script.lang || "js") } loaderContext.callback( null, descriptor.script.content, descriptor.script.map ) return } // styles if (query.type === `style` && query.index != null) { const style = descriptor.styles[query.index] if (appendExtension) { loaderContext.resourcePath += "." + (style.lang || "css") } loaderContext.callback( null, style.content, style.map ) return } // custom if (query.type === "custom" && query.index != null) { const block = descriptor.customBlocks[query.index] loaderContext.callback( null, block.content, block.map ) return } }總結(jié)
通過(guò) vue-loader 的源碼我們看到一個(gè) Vue SFC 在整個(gè)編譯構(gòu)建環(huán)節(jié)是怎么樣一步一步處理的,這也是得益于 webpack 給開(kāi)發(fā)這提供了這樣一種 loader 的機(jī)制,使得開(kāi)發(fā)者通過(guò)這樣一種方式去對(duì)項(xiàng)目源碼做對(duì)應(yīng)的轉(zhuǎn)換工作以滿足相關(guān)的開(kāi)發(fā)需求。結(jié)合之前的2篇有關(guān) webpack loader 源碼的分析,大家應(yīng)該對(duì) loader 有了更加深入的理解,也希望大家活學(xué)活用,利用 loader 機(jī)制去完成更多貼合實(shí)際需求的開(kāi)發(fā)工作。
文章首發(fā)于個(gè)人github blog: Biu-blog,歡迎大家關(guān)注~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/102787.html
摘要:在一個(gè)構(gòu)建過(guò)程中,首先根據(jù)的依賴類(lèi)型例如調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)應(yīng)的模塊。 文章首發(fā)于個(gè)人github blog: Biu-blog,歡迎大家關(guān)注~ Webpack 系列文章: Webpack Loader 高手進(jìn)階(一)Webpack Loader 高手進(jìn)階(二)Webpack Loader 高手進(jìn)階(三) Webpack loader 詳解 loader 的配置 Webpack...
webpack的loaders是一大特色,也是很重要的一部分。這遍博客我將分類(lèi)講解一些常用的laodershowImg(https://segmentfault.com/img/remote/1460000005742040); 一、loaders之 預(yù)處理 css-loader 處理css中路徑引用等問(wèn)題 style-loader 動(dòng)態(tài)把樣式寫(xiě)入css sass-loader scss編譯器 ...
摘要:如果函數(shù)沒(méi)有返回值的話,那么進(jìn)入到下一個(gè)的函數(shù)的執(zhí)行階段。這也是異步化的一種方式如果執(zhí)行后有返回值,執(zhí)行開(kāi)始下一個(gè)執(zhí)行以上就是對(duì)于在構(gòu)建過(guò)程中執(zhí)行流程的源碼分析。 文章首發(fā)于個(gè)人github blog: Biu-blog,歡迎大家關(guān)注~ Webpack 系列文章: Webpack Loader 高手進(jìn)階(一)Webpack Loader 高手進(jìn)階(二)Webpack Loader 高手...
摘要:基本環(huán)境搭建就不展開(kāi)講了一插件篇自動(dòng)補(bǔ)全前綴官方是這樣說(shuō)的,也就是說(shuō)它是一個(gè)自動(dòng)檢測(cè)兼容性給各個(gè)瀏覽器加個(gè)內(nèi)核前綴的插件。 上一篇博客講解了webpack環(huán)境的基本,這一篇講解一些更深入的內(nèi)容和開(kāi)發(fā)技巧?;经h(huán)境搭建就不展開(kāi)講了showImg(http://static.xiaomo.info/images/webpack.png); 一、插件篇 1. 自動(dòng)補(bǔ)全css3前綴 autop...
摘要:,我想大家應(yīng)該都知道或者聽(tīng)過(guò),是前端一個(gè)工具可以讓各個(gè)模塊進(jìn)行加載預(yù)處理再進(jìn)行打包。 webpack,我想大家應(yīng)該都知道或者聽(tīng)過(guò),Webpack是前端一個(gè)工具,可以讓各個(gè)模塊進(jìn)行加載,預(yù)處理,再進(jìn)行打包。現(xiàn)代的前端開(kāi)發(fā)很多環(huán)境都依賴webpack構(gòu)建,比如vue官方就推薦使用webpack.廢話不多說(shuō),我們趕緊開(kāi)始吧. 第一步、安裝webpack 新建文件夾webpack->再在web...
閱讀 3332·2021-09-07 10:10
閱讀 3646·2019-08-30 15:44
閱讀 2653·2019-08-30 15:44
閱讀 3124·2019-08-29 15:11
閱讀 2293·2019-08-28 18:26
閱讀 2806·2019-08-26 12:21
閱讀 1180·2019-08-23 16:12
閱讀 3141·2019-08-23 14:57