zoukankan      html  css  js  c++  java
  • ts-loader如何与vue单文件组件衔接

    .ts-loader是如何与vue单文件组件衔接作用的

     

    首先看一下官方的starter pack

     

     

     

     

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

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

     

    从文档上可以看到,处理单文件组件安装了 typescript 和 ts-loader这两个依赖。

     

     

     

    ts-loader是如何处理.vue单文件组件的,

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

     

    ———————————————————————————————

     

     

    首先再来回忆一下vue-loader+VueLoaderPlugin的处理过程:

     

     

     

    vueloaderplugin在webpack初始化的阶段,

     

    vueloaderplugin扩展了开发者module.rule的配置,加入了vue-loader内部提供的pitcher-loader(即:pitcher这个rule,它的use是pitcher-loader),  

           (pitcher的resourceQuery是 request带”vue”query的 (如xxx.xx?vue&xxx) )

     

     

    并以下面这个顺序将rules重新组合

     

    [pitcher,…clone Rules,…vue-loader] (将vue-loader放到最后,将pitch-loader放到最开始,中间是被重写过fakeResourcepath的clone Rules)

     

    (pitcher-loader的匹配条件是,request中带”vue”这个query  (如xxx.xx?vue&xxx))

     

     

     

     

    Step1:

    当处理一个.vue文件的时候,vue-loader会判断,如果request不带type=vue,会生成下面这一大段js module:

     

    这就是第一步, 这里一个.vue文件会被处理成下面的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&"

     

     

    /* 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:

    webpack中的acron开始对这个新生成的一坨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的..

     

    然后我们debug会发现,这个时候处理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&"

     

     

    问题: 为什么script block的部分生成的request。。直接就判定附带有ts-loader了

     

     

     

     

    继续向前看,

     

     

     

    在最后生成上面这坨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,看看为什么这里会把ts-loader也加入了进来

     

     

     

     

    注意,此时是在对step2中收集依赖时收集的 import script from "./index.vue?vue&type=script&lang=ts&" 进行操作。

     

     

    继续向前debug,下面要进行exec了, 可以看到 rules是webpack处理得到的所有rules 要从里面筛选出本次构建module可用的loaders

     

     

     

     

    exec里面会执行run方法, run方法会接触到这一大坨过滤条件, 如果都满足了,才会将这个loader加入到result中

     

     

    这个方法里有一个rule.resourceQuery, 这时候会发现对/.tsx?$/结尾的这种rule的resourceQuery已经被vueLoaderPlugin改写过了

     

     

     

     

     

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

     

          会对webpack的所有配置的rules中除了,/.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

  • 相关阅读:
    Linux 系统中用户切换(su user与 su
    linux 用户打开进程数和文件数调整
    hive sql 语法详解
    iOS
    iOS
    MySQL的事务的处理
    iOS
    iOS AOP编程思想及实践
    iOS 静态库和动态库(库详解)
    iOS 沙盒目录结构及正确使用
  • 原文地址:https://www.cnblogs.com/eret9616/p/11817277.html
Copyright © 2011-2022 走看看