ts-loader如何與vue單文件組件銜接

.ts-loader是如何與vue單文件組件銜接做用的vue

 

 

 

 

https://github.com/microsoft/TypeScript-Vue-Starternode

https://www.npmjs.com/package/ts-loaderwebpack

 

從文檔上能夠看到,須要安裝 typescript 和 ts-loader這兩個依賴git

 

 

 

 

ts-loader是如何處理.vue單文件組件的,github

rule的配置裏,ts-loader的test是以.ts文件結尾的啊,下面研究下web

 

 

 

———————————————————————————————typescript

 

 

首先再來回憶一下vue-loader+VueLoaderPlugin的處理過程:npm

 

 

 

vueloaderplugin在webpack初始化的階段,api

vueloaderplugin擴展了開發者module.rule的配置,加入了vue-loader內部提供的pitcher-loader(即:pitcher這個rule,它的use是pitcher-loader),  ui

       (pitcher的resourceQuery是 request帶」vue」這個query的 (如xxx.xx?vue&xxx) )

 

 

並以這樣的順序將rule從新組合

[pitcher,…clone Rules,…vue-loader] (將vue-loader放到最後,將pitch-loader放到最開始)

 

pitcher-loader的匹配條件是,request中帶」vue」這個query  (如xxx.xx?vue&xxx)

 

 

 

 

Step1:

當處理一個.vue文件的時候,vue-loader會判斷,若是request不帶type=vue,會生成下面這一大段js module:

 

 

"import { render, staticRenderFns } from "./index.vue?vue&type=template&id=2964abc9&"

import script from "./index.vue?vue&type=script&lang=ts&"

export * from "./index.vue?vue&type=script&lang=ts&"

 

 

/* normalize component */

import normalizer from "!../node_modules/vue-loader/lib/runtime/componentNormalizer.js"

var component = normalizer(

  script,

  render,

  staticRenderFns,

  false,

  null,

  null,

  null

  

)

 

/* hot reload */

if (module.hot) {

  var api = require("/Users/huhao/Desktop/demo/node_modules/vue-hot-reload-api/dist/index.js")

  api.install(require('vue'))

  if (api.compatible) {

    module.hot.accept()

    if (!api.isRecorded('2964abc9')) {

      api.createRecord('2964abc9', component.options)

    } else {

 

 

 

 

 

Step2:

而後開始對這個新生成的一坨jsmodule進行處理,依賴收集的過程當中,會拿到

 

import { render, staticRenderFns } from "./index.vue?vue&type=template&id=2964abc9&"

 

import script from "./index.vue?vue&type=script&lang=ts&" 

export * from "./index.vue?vue&type=script&lang=ts&"

 

這些行request,而後對每一個request進行resolve,建立獨立的module..

 

由於request帶vue這個query,因此會先被pitcher-loader處理,pitcher在runLoaders過程當中操做,會第一個執行,剔除掉eslint-loader,剔除pitcher自身,根據不一樣的type=xxx 返回一段新的request,

 

 

..有template的..

..有style的..

..有script的..

 

而後咱們會發現這個時候處理script的生成的request,附帶了ts-loader了。

 

 

問題: 爲何script的部分生成的request。。直接就斷定附帶有ts-loader了

 

"/Users/huhao/Desktop/demo/node_modules/ts-loader/index.js??ref--2!/Users/huhao/Desktop/demo/node_modules/vue-loader/lib/index.js??vue-loader-options!/Users/huhao/Desktop/demo/src/index.vue?vue&type=script&lang=ts&"

 

 

咱們向前看,

 

 

在最後生成上面這坨request的過程前,會先通過build的過程,

在調用棧doBuild的時候,要執行runLoaders方法的時候,this.loaders就已經包括ts-loader了

 

 

 

 

 

🤔

 

 

 

在build以前是建立module和resolve的過程,看一下建立module的過程,

 

 

normalModule.factory中 會使用rulest.exec({})對resouce("./index.vue?vue&type=script&lang=ts&")進行操做,根據webpack的rule規則,去和webpack的options中配置的loader進行過濾,解析出本次構建module過程當中可使用的loader,

 

 

 

 

 

 

 

 

注意,此時是在對step2中收集依賴時收集的 import script from "./index.vue?vue&type=script&lang=ts&" 進行操做。

 

 

下面要進行exec了, 能夠看到 rules是webpack處理獲得的全部rules 要從裏面篩選出本次構建module可用的loaders

 

 

 

 

 

exec裏面會執行run方法, run方法會接觸到這一大坨過濾條件, 若是都知足了,纔會將這個loader加入到result中

 

 

 

 

 

這個方法裏有一個rule.resourceQuery, 這時候會發現對/.tsx?$/結尾的這種rule的resourceQuery其實已經被vueLoaderPlugin改寫過了 ,

 

 

在vue-loader的 plugin.js的 cloneRule方法中:

 

對webpack的除了,/.vue$/的rule,的resource過濾和resourceQuery過濾重寫了…

 

 

 

 

 

 

看一下重寫的resourceQuery裏:

 

 

加了這句話,

 

  const fakeResourcePath = `${currentResource}.${parsed.lang}`

 

 

主要是這句話,fakeResourcePath…

 

fakeResourcePath的值是

 

 

 

因此在exec的過程當中,拿webpack的rules過濾loaders的過程當中,ts-loader會加入構建,由於..

全部resourcePath被加入了parsed.lang了

 

 

 

 

 

由於ts-loader的條件是

 

 

 

 

 

’ts’或’tsx’結尾的能經過他的條件篩選

 

 

 

資料:

1. ruleSet的使用機制: https://github.com/CommanderXL/Biu-blog/issues/30

相關文章
相關標籤/搜索