• 原来 vue3 文件编译是这样工作的!看完后更懂vue3了


    前言

    我们每天写的vue代码都是写在vue文件中,但是浏览器却只认识htmlcssjs等文件类型。所以这个时候就需要一个工具将vue文件转换为浏览器能够认识的js文件,想必你第一时间就想到了webpack或者vite。但是webpackvite本身是没有能力处理vue文件的,其实实际背后生效的是vue-loader@vitejs/plugin-vue。本文以@vitejs/plugin-vue举例,通过debug的方式带你一步一步的搞清楚vue文件是如何编译为js文件的,看不懂你来打我

    举个例子

    这个是我的源代码App.vue文件:

    <template>
      <h1 class="msg">{{ msg }}h1>
    template>
    
    <script setup lang="ts">
    import { ref } from "vue";
    
    const msg = ref("hello word");
    script>
    
    <style scoped>
    .msg {
      color: red;
      font-weight: bold;
    }
    style>
    

    这个例子很简单,在setup中定义了msg变量,然后在template中将msg渲染出来。

    下面这个是我从network中找到的编译后的js文件,已经精简过了:

    import {
      createElementBlock as _createElementBlock,
      defineComponent as _defineComponent,
      openBlock as _openBlock,
      toDisplayString as _toDisplayString,
      ref,
    } from "/node_modules/.vite/deps/vue.js?v=23bfe016";
    import "/src/App.vue?vue&type=style&index=0&scoped=7a7a37b1&lang.css";
    
    const _sfc_main = _defineComponent({
      __name: "App",
      setup(__props, { expose: __expose }) {
        __expose();
        const msg = ref("hello word");
        const __returned__ = { msg };
        return __returned__;
      },
    });
    
    const _hoisted_1 = { class: "msg" };
    function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
      return (
        _openBlock(),
        _createElementBlock(
          "h1",
          _hoisted_1,
          _toDisplayString($setup.msg),
          1
          /* TEXT */
        )
      );
    }
    
    __sfc__.render = render;
    export default _sfc_main;
    

    编译后的js代码中我们可以看到主要有三部分,想必你也猜到了这三部分刚好对应vue文件的那三块。

    • _sfc_main对象的setup方法对应vue文件中的