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

相关文章
相关标签/搜索