从0到1手把手教你实现vite系列--05-解析.vue文件,你知道vite为何可以加载.vue文件吗?

1,886 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

人生苦短,我们要:

image.png

继续接着上个文章,我们现在已经解决http://localhost:8088/@modules/vue请求问题,刷新页面,我们可以看到这个样子

但是我们可以看到,.vue文件是红的哦,没有被加载成功,接下来就要解决这问题啦~~

创建新的插件vite\src\serverVuePlugin.js

// import { fstat } from 'fs'
const fs = require('fs').promises
const { Console } = require('console')
const path = require('path')
 function vuePlugin({app,root}){
app.use(async (ctx,next)=>{
    if(!ctx.path.toString().endsWith('.vue')){
        return next()
    }
    const filePath = path.join(root,ctx.path)
    const content = await fs.readFile(filePath,'utf-8')
    // 解析模板
    // sfc是编译单模板的   node_modules\@vue\compiler-sfc\dist\compiler-sfc.cjs.js
    const compiler = require(path.resolve(root, 'node_modules','@vue/compiler-sfc/dist/compiler-sfc.cjs.js'))
    console.log('compiler')
    console.log(compiler)
})
}
exports.vuePlugin = vuePlugin

来个图,更清晰,就是我们需要找到这个node_modules@vue\compiler-sfc\dist\compiler-sfc.cjs.js,来编译我们的模板

先把插件放入server.js里先跑一把看看结果如何~~

  • 代码怎么写就不放了,直接看图吧,插件引入就两行代码哦~~

来来来,跑起来

打印出来了这个东西哇~~

compiler
{
  MagicString: <ref *1> [Function: MagicString] {
    Bundle: [Function: Bundle],
    SourceMap: [Function: SourceMap],
    default: [Circular *1]
  },
  babelParse: [Function: parse],
  extractIdentifiers: [Function: extractIdentifiers],
  generateCodeFrame: [Function: generateCodeFrame],
  isInDestructureAssignment: [Function: isInDestructureAssignment],
  isStaticProperty: [Function: isStaticProperty],
  walkIdentifiers: [Function: walkIdentifiers],
  shouldTransformRef: [Function: shouldTransform],
  transformRef: [Function: transform],
  transformRefAST: [Function: transformAST],
  compileScript: [Function: compileScript],
  compileStyle: [Function: compileStyle],
  compileStyleAsync: [Function: compileStyleAsync],
  compileTemplate: [Function: compileTemplate],
  parse: [Function: parse],
  rewriteDefault: [Function: rewriteDefault],
  walk: [Function: walk]
}

来分析一下:我们需要这两个东西来实现功能哦~·

  • compileTemplate: [Function: compileTemplate], 这个就是编译我们模板的
  • parse: [Function: parse], 这个就是解析的

开始继续写插件代码,使用关键函数实现功能

  • 我们观察一下大佬们是如何实现这个功能的
  • 我们发现,query会有不同的
  • 改了这些代码,我用图片把改动地方标记出来哦
 // sfc是编译单模板的   node_modules\@vue\compiler-sfc\dist\compiler-sfc.cjs.js
    const {compileTemplate,parse} = require(path.resolve(root, 'node_modules','@vue/compiler-sfc/dist/compiler-sfc.cjs.js'))
    // console.log('compiler')
    // console.log(compiler)
    // 下面这个写法是我们要参考一下图片
    if(!ctx.query.type){
        // 访问  /App.vue
        let res = parse(content)
        console.log('res')
        console.log(res)
    }

  • 跑一把看一下结果
  • 可以看到我们的代码就被解析出来了呢,
  • descriptor ,template,scriptSetup,是被解析的结果
  • 处理一下空格,分号,换行,$1代表前面东西保留,export_default变成const __script

困了,今天先写到这里,睡醒继续

欢迎大家指出文章需要改正之处~
学无止境,合作共赢 在这里插入图片描述

欢迎路过的小哥哥小姐姐们提出更好的意见哇~~