1.Vue3核心源码解析 (一) : 源码目录结构
2.Loader源码分析-Vue Loader v15
3.Webpack 案例 —— vue-loader 原理分析
4.vue-loaderä¸vue-cli3
5.vue3源码学习--编译阶段汇总
Vue3核心源码解析 (一) : 源码目录结构
通过软件框架源码阅读,深入理解框架运行机制,API设计、原理及流程成为开发者进阶的关键。Vue 3源码相较于Vue 2版本的改进明显,采用Monorepo目录结构,修改logstash源码引入TypeScript作为开发语言,新增特性和优化显著。
启动Vue3源码,最新版本为V3.3.0-alpha.5。下载后进入core文件夹,使用Yarn进行构建。安装依赖后,执行npm run dev启动调试模式,可直观查看完整的源代码目录结构。
核心模块包括compiler-core、compiler-dom、runtime-core、runtime-dom。正零源码compiler模块在编译阶段负责将.vue文件转译成浏览器可识别的.js文件,runtime模块则负责程序运行时的处理。reactivity目录内是响应式机制的源码,遵循Monorepo规范,每个子模块独立编译打包,通过require引入。
构建Vue 3版本可使用命令,构建结果保存在core\packages\vue\dist目录下。选择性构建可通过命令实现,具体参数配置在core/rollup.config.js中查看。对于客户端编译模板,需构建完整版本,而使用Webpack的vue-loader时,.vue文件中的模板在构建时预编译,无需额外编译器。浏览器直接打开页面时采用完整版本,构建工具如Webpack引入运行时版本。Vue的盗相册源码构建脚本源码位于core/scripts下。
Loader源码分析-Vue Loader v
vue-loader 是什么
简单来说,vue-loader 的作用是将 .Vue 文件编译成 .js 文件,这样就可以在浏览器中运行,同时也可以在 node 环境中使用 vue-server-render 进行运行。
vue-loader 的改动
相较于之前的版本,vue-loader 进行了许多重要的改动,具体细节可以参考官方的迁移指南。
vue-loader 的编译过程
vue-loader 的处理流程可以大致分为以下几个部分:
vue-loader 入口函数
vue-loader 的入口代码并不多,我将入口函数的流程绘制了一个简单的 UML 图,通过这个图可以快速对流程有一个初步的了解。
vue-loader 入口函数主要做了以下几件事:
通过上面的 UML 图可以看出,.vue 文件初次编译时会走生成 code 的流程,那么生成的 code 究竟是什么呢?
通过调试 vue-loader,将 code 打印出来,仔细观察图中红色框中的部分。
可以发现在几句 import 中,都是从 source.vue 获取对象,并且路径上携带了参数,可乐溯源码这些参数就是 resourceQuery,type 有三种不同类型,分别是 template | script | styles。
这些 import 会继续触发新一轮的 vue-loader 执行,于是接下来就到了途中 resourceQuery 有 type 的情况。
下面是进行了适当删减后的源码,保留了上述涉及到的代码,对代码本身感兴趣的可以浏览。
parse .vue 组件解析
parse 方法内部处理了 vue SFC 文件,前面提到过,编译的方法默认是通过 vue-template-compiler 处理。
主要是通过 compiler.parseComponent 函数对 .vue 文件进行编译。
那么 vue-template-compiler 究竟是什么呢?
在了解 vue-template-compiler 之前,我对 vue 的编译过程有些了解,既然它们都是处理 vue SFC 文件,那么它们会不会是同一份代码呢?抱着疑问的态度,我们先看看 vue-template-compiler 的 readme.md。
This 淘品源码package is auto-generated. For pull requests please see src/platforms/web/entry-compiler.js.
在 readme.md 中可以看到官方对它的说明,实际上 vue-template-compiler 是一份自动生成的代码,它本质就是 vue 中的 sfc/parse。
但今天的主角并不是 vue-template-compiler,也不是 sfc/parse,我会在后面的篇章中对 vue build 的过程做一个详细的解读。
parse 流程 vue-loader 推导策略
在 vue-loader 入口函数分析中已经可以了解到,入口函数最终会生成一个 code,这个 code 包含了几个 import 语句,import 语句都含有 vue 标识并且标明了不同的分块类型。
这些 import 语句会被 VueLoaderPlugin 捕捉并做推导策略处理。
VueLoaderPlugin
老规矩,先来看 VueLoaderPlugin 的代码。
代码删减后及其简单,就一件事:注入 pitcher-loader,用于处理 vue 分块 loader 推导。
pitcher-loader
VueLoaderPlugin 的主要作用就是注入 pitcher-loader,由此可知,实际处理推导过程的是 pitcher-loader,VueLoaderPlugin 只不过是一个 loader 的注入器。
那么 pitcher-loader 是怎么做 loader 推导的呢?
前面提到入口函数生成的 code,code 中包含 import 语句。
这些 import 语句会触发 pitcher-loader,pitcher 根据 resourceQuery 来区分不同块,并生成不同的 loader request。
loader 推导流程总结
把上述过程汇聚成一张 UML 图,通过这张图可以对整个流程有一个清晰的认识。
vue-loader 的整体过程可以划分为以下几个部分:
Webpack 案例 —— vue-loader 原理分析
两个核心问题:一、Vue SFC 文件包含了多种内容格式:样式、脚本、模板以及其他自定义块,Vue-loader 如何针对这些不同格式的内容进行处理和解析?二、针对Vue SFC中不同内容块的解析,Vue-loader 如何复用其他loader,特别是针对less 定义的样式块时,Vue-loader 是如何调用less-loader 来处理的?
首先,我们需要理解Vue-loader的工作原理。它主要包含了三大部分:插件、预处理阶段和核心内容处理阶段。在处理过程中,Vue-loader 通过插件扩展了 webpack 配置信息,实现对SFC的高效解析。
预处理阶段,Vue-loader 插件通过apply函数在webpack的配置中插入动态loader(pitcher),并且复制原有的loader规则,使新创建的规则能够识别SFC内容中的不同格式块。这里的pitcher和原有的loader规则配合,为后续的解析过程打下了基础。
接着,我们来到核心内容处理阶段。在这一阶段,经过一系列loader的逐层处理,Vue-loader 会分别针对样式、脚本、模板以及其他自定义块完成各自的转换。例如,在引入less 定义的样式块时,经过pitcher处理后的import路径会被less-loader进一步解析,实现样式定义到实际样式代码的转换。
简而言之,Vue-loader 通过巧妙地利用loader的复用和插件的动态扩展,不仅简化了处理流程,提高了代码的可读性和可维护性,还保证了对于不同格式内容块的高效解析。在处理过程中,遵循了webpack loader编写的一般规范,使其在应用中具有较高的通用性。
综上所述,Vue-loader 基于其设计原理和运行机制,成功实现了针对Vue SFC中不同类型内容块的高效解析与复用其他loader的功能。不仅简化了开发人员的工作流程,还提升了代码的扩展性和灵活度,是webpack生态中一个非常实用且强大的组件。
vue-loaderä¸vue-cli3
æ¥çææ¡£Vue Loader æ¯ä¸ä¸ª webpack ç loader(å¨vue-cliä¸å·²èªå¨éæ)ï¼ä»¥ä¸åè½é½ä¾èµäºVue Loader:
å½ Vue Loader ç¼è¯åæ件ç»ä»¶ä¸ç <template> åæ¶ï¼å®ä¹ä¼å°ææéå°çèµæº URL 转æ¢ä¸º webpack 模å请æ±ãå æ¤å¨ææ·»å /æ´æ¹çèµæºéç»å¯¹è·¯å¾éè¦ä½¿ç¨ require å¤çã
é»è®¤ä¸åæ ç¾/ç¹æ§çç»åä¼è¢«è½¬æ¢ï¼ä¸è¿äºç»åæ¶å¯ä»¥ä½¿ç¨ transformAssetUrls é项è¿è¡é ç½®çã
( å¦é ç½®é¢å¤ç <style> åä½¿ç¨ css-loader ï¼ä¹å¯ä»¥ä½¿ CSS ä¸çèµæº URL åæ模å请æ±ã)
Vue Loader ä¼æ ¹æ® lang ç¹æ§ä»¥åä½ webpack é ç½®ä¸çè§åèªå¨æ¨æåºè¦ä½¿ç¨çå ¶ä» loaderã
æäºé¢å¤çå¨å¯¹ >>> ä¸æ¯æï¼æ¤æ¶å¯ä»¥ä½¿ç¨ /deep/ æ ::v-deep æä½ç¬¦åè代ä¹ââ两è é½æ¯ >>> çå«åã
æç´æ¥
å¯èªè¡å¨ process.env 对象ä¸å®ä¹éè¦ä½¿ç¨çåé
ä¸è¬çº¦å® NODE_ENV 为ç¯å¢åéå称
å¨é¡¹ç®ä¸å¯ä»¥æ ¹æ®ä¸åç¯å¢å¼è¿è¡å·®å¼åé ç½®
å¨vue-cli3æ建ç项ç®ä¸,é»è®¤ num run start ç¯å¢å¼ä¸º development , num run build ç¯å¢å¼ä¸º production ,å½éè¦å ¶ä»ç¯å¢æ¶,å¯å®è£ cross-env æ件
并å¨package.jsonä¸è¿è¡å¦ä¸é ç½®
å npm run test æ¶,è·åçç¯å¢å¼å³ä¸º test
å¨æ ¹ç®å½ä¸å建 vue.config.js ä¸è¿è¡é ç½®
vue3源码学习--编译阶段汇总
从vue-loader开始,我们逐步探索vue/compiler-core包的源码,完成了编译阶段的解析(忽略了compiler-ssr部分)。 涉及的包包括:vue-loader:基于webpack的入口
vueLoaderPlugin:处理核心操作
@vue/compiler-sfc:处理script、template和style
compiler-dom:处理template,与compiler-core协同工作
compiler-core:处理template的核心部分
vue-loader首先安装vueLoaderPlugin,主要负责匹配资源并调用相应方法。script部分通过@vue/compiler-sfc的compileScript处理,其他如template和style则根据其类型调用相应处理函数。 编译流程中,script通过babel将JavaScript转换为AST节点,然后进行处理。template则通过compiler-dom和compiler-core转换为浏览器可识别的JavaScript代码。CSS变量和scopeId也是在这个阶段进行处理的。 在dev模式下,render function会被分离出来以支持热模块替换(HMR),而prod模式下,这些代码会被整合到setup函数中,以提高代码效率。 最后,总结整个编译阶段,对Vue源码有了深入理解,不再是神秘的魔法,而是清晰的流程。希望这些内容对您有所帮助,祝大家新春快乐!