关于 vue/cli 脚手架实现项目编译运行的源码解析

1.vue项目运行命令解析

在日常开发中,vue 项目通过vue-cli-service脚手架包将项目运行起来,常用的命令例如:

npm run serve

npm run build

上述执行命令实际一般对应为项目中 package.json 文件的 scripts属性中编写的脚本命令,在项目目录中的终端运行时即匹配到对应的脚本命令,例如:

匹配对应的脚本命令,例如npm run serve ,即运行 vue-cli-service serve 脚本命令,此时,会去加载项目中 node_modules 文件夹中的.bin 文件找到对应的执行文件,如下:

 2.关于 node_modules 中 vue-cli-service 文件的加载过程

在加载 vue-cli-service 文件的过程,我们知道mode_modules 中.bin 文件对应的是链接文件,即实际会找到 node_modules 文件夹下的vue-cli-service 依赖包中的对应vue-cli-service.js文件加载运行

即找到 node_modules 文件夹下的@vue包下面的cli-service包下的vue-cli-service.js 文件进行运行,如下:

可以看到.bin 文件中的 vue-cli-service 文件与@vue/cli-service/bin/vue-cli-service.js 文件内容一致,实际运行的也是@vue/cli-service/bin/vue-cli-service.js,可以发现文件中主要引入了../lib/Service文件,并创建 service 类,调用 service 类中的 run 方法,接下来就是对应找到service 类中对应的 run 方法的运行内容。

注意:传入 run 方法中的 command在运行 npm run serve时,这时的 command即等于字符串 serve  即脚本命令中的后面的参数

我们找到/lib/Service 文件,如下:

可以看到 run 方法中主要调用了 fn 函数,fn 从方法中的 command中取出,command从 this.commands通过[name]取出,即 this.commands['serve'],但是在该文件中可以看到 commands 并没有什么初始化赋值操作,如下:

此时回到 run 方法中可以看到在执行 fn 函数前,主要执行了这两个方法,我们主要看 init 初始化函数,setPluginsToSkip 方法主要是做对一些内置 plugins 进行忽略

    // --skip-plugins arg may have plugins that should be skipped during init()
    // 需要忽略的默认 plugins
    this.setPluginsToSkip(args)

    // load env variables, load user config, apply plugins
    this.init(mode)

找到 init() 方法, 如下

在 init 方法中我们主要看这段代码,其他代码是主要做一些配置处理,实际主要是看 apply 方法的的调用

    this.plugins.forEach(({ id, apply }) => {
      if (this.pluginsToSkip.has(id)) return
      apply(new PluginAPI(id, this), this.projectOptions)
    })

可以看到是对文件中的 this.plugins 进行循环,结构每个 item 中的 apply 方法进行调用,我们找到 plugins 的初始化,如下:

可以看到,Service 类中初始化是对 plugins 赋值通过调用了 resolvePlugins 方法进行初始化,如下:

在resolvePlugins 方法中我们可以看到遍历了builtInPlugins,进行赋值给 plugins 并返回

此时回到 init 方法中对 this.plugins的遍历即 apply 调用:

我们即可得知,apply 的调用,是对 resolvePlugins方法中的的 require(id)调用,如下:

在 run serve的时候,实际即对应 require('./commands/serve')去加载对应该文件,我们进入到该文件, 如下:

查看./commands/serve文件可以看到,文件主要导出了上述的回调函数,回调函数内部调用了api.registerCommand函数,关于为什么可以取到到 api.registerCommand调用,我们就要回到apply() 函数调用的时候的传参,如下:

可以看到是创建了 PluginAPI这个类,并把 id 传入(./commands/serve等等)及当前上下文 this,我们找到 PluginAPI的类文件,如下:

可以看到PluginAPI类中的定义了registerCommand方法,而该方法的内容中可以看到对 this.service.commands[name] 赋值了{fn,opts}对象,这就解释了前面@vue/cli-service/bin/vue-cli-service.js中的 run 方法为什么可以取出 fn 函数进行调用,即下图:

此时我们最后来看 fn函数,对应的是什么内容,如下:

最后我们去看 serve()函数内容, 如下:

3.找到 webpack加载文件处

可以看到熟悉的Starting development server...,即项目运行时终端中会打印的信息,继续往下查看该函数,最终可以看到运用 webpack 包,并传入config配置解析,并使用 WebpackDevServer 这个 plugin,即开启本地运行的插件, 如下:

函数的最后我们可以看到,启动了 server 的监听函数,即成功将项目编译完成开启本地服务运行,如下:

4.总结

通过解析vue-cli-serve的源码,以上便是 vue-cli脚手架 运用 webpack 进行内部封装,如何实现脚手架内将项目解析打包,加载在内存中,并拉起本地服务,实现本地运行vue项目的流程。

npm run serve -> vue-cli-service.js ->service.run ->service.init ->apply ->require('./commanmds/serve') ->PluginAPI.registerCommand -> serve()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/875743.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python 课程5-NumPy库

在数据处理和科学计算中,NumPy 是一个非常强大且基础的库。除了基本的创建数组功能之外,NumPy 提供了许多强大的函数和方法,用于执行高级的矩阵运算、统计分析、逻辑操作等。以下是一些常用且非常有用的 NumPy 指令,涵盖了创建数组…

java: 程序包org.junit.jupiter.api不存在

明明idea没有报错,引用包也没问题,为啥提示java: 程序包org.junit.jupiter.api不存在? 配置!还TMD是配置! 如果是引用包的版本不对或者其他,直接就是引用报错或者pom里面飘红了。 这个应该是把generat…

设置使用阿里云服务器DNS

由于云服务器是从腾讯云迁移到阿里云,然后使用ssl验证时一直无法使用dns验证,也无法创建三级域名,原来需要把阿里云服务器改成阿里云的dns使用 如果使用其他服务器DNS会下面会显示当前DNS服务器,

冯诺依曼体结构与系统

冯诺依曼结构 我们的计算机,以及服务器,还有我我们日常使用的洗衣机都遵循冯诺依曼体结构。 以我们日常使用qq聊天时举例,冯诺依曼体结构可以这样画 截至目前,我们所认识的计算机,都是有一个个的硬件组件组成 输入单元…

基于SpringBoot+Vue+MySQL的美术馆管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着文化艺术产业的蓬勃发展,美术馆作为展示与传播艺术的重要场所,其管理工作变得日益复杂。为了提升美术馆的运营效率、优化参观体验并加强艺术品管理,我们开发了基于SpringBootVueMySQL的美…

SAP B1 营销单据 - 单据字段介绍(中)

背景 营销单据,SAP B1 中一群神秘的单据,在官方说明文档中并未指明【营销单据】范围,却经常使用这一说法。它们结构相似,在 用户定义字段(UDF) 功能里统一受【营销单据】部分增加字段的影响,可以相互复制(…

POI生成Excel文件增加数据验证(下拉序列)

POI版本为5.2.2 正常的如果不超过255字符的数据验证可以参照如下代码&#xff1a; /*** <p>设置某列的数据验证</p>* param Sheet 作用于哪一个sheet* param colIndex 需要增加数据验证的列的索引* String[] names 数据验证的序列&#xff0c;就是excel下拉列表的内…

codesys将自定义的功能块或者函数保存到本地库

将通过ST代码实现的自定义功能保存到codesys的本地库&#xff0c;其他project可以直接实现调用。提高灵活性和效率。 1、创建库工程 这里可能会提示涉及个别库没有安装或版本更新&#xff0c;根据提示安装对应库或更新即可。 2、添加功能块和函数 3、编写功能块和函数的参数定…

【Linux】查看操作系统开机时初始化的驱动模块列表的一个方法

这个方法是摸索出来的&#xff0c;也不一定对&#xff1a; 1、驱动层module_init(module_init_function)作为模块初始化&#xff0c;并且提供模块内部初始化的函数名&#xff1b; 2、找到所有驱动目录drivers下所有module_init(module_init_function)&#xff0c;在内核6.9.0…

js 深入理解生成器

目录 概述1 . 生成器基础2. 与普通函数的区别3. 通过 yield 中断执行3.1 yield 是干嘛的&#xff1f;3.2 yield 和 return 的区别3.3 每个生成器对象作用域都是独立的3.4 yeild 的使用位置3.5 生成器对象作为可迭代对象3.6 使用 yield 实现输入和输出3.6.1 yield实现输入3.6.1 …

4G物联网智能电表是什么?什么叫4G物联网智能电表?

4G物联网智能电表是一种结合了4G无线通信技术的新型电能计量设备&#xff0c;用于实时采集和传输用户的用电数据。它通过集成现代信息技术和电力电子技术&#xff0c;不仅能够精确测量电力消耗&#xff0c;还能实现远程数据传输、数据分析、远程控制等多种功能。本文将详细介绍…

【运维监控】influxdb 2.0+grafana 监控java 虚拟机以及方法耗时情况(2)

运维监控系列文章入口&#xff1a;【运维监控】系列文章汇总索引 文章目录 四、grafana集成influxdb监控java 虚拟机以及方法耗时情况1、添加grafana数据源2、添加grafana的dashboard1&#xff09;、选择新建dashboard方式2&#xff09;、导入dashboard 3、验证 关于java应用的…

CSS学习17--CSS3 过渡、2D变形、3D变形、动画

CSS3 过渡、2D变形、3D变形、动画 一、过渡二、2D变形 transform1.移动 translate2.缩放 scale3. 旋转 rotate4. 倾斜 skew 三、3D变形1. rotateX&#xff08;&#xff09;rotateY&#xff08;&#xff09; rotateZ&#xff08;&#xff09;2. 体会透视 perspective3. translat…

[数据集][目标检测]车油口挡板开关闭合检测数据集VOC+YOLO格式138张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;138 标注数量(xml文件个数)&#xff1a;138 标注数量(txt文件个数)&#xff1a;138 标注类别…

CleanMyMac X2024破解版mac电脑清理工具

今天&#xff0c;我要跟大家分享一个让我彻底告别电脑卡顿的秘密武器——CleanMyMac X。这不仅仅是一款普通的清理工具&#xff0c;它是你电脑的私人健身教练&#xff0c;让电脑焕发青春活力&#xff01; CleanMyMac直装官方版下载地址&#xff1a; http://wm.makeding.com/i…

【通用分割模型】SAM 2论文翻译

文章目录 摘要1 引言2 相关工作3 任务&#xff1a;可提示视觉分割4 模型5 数据5.1 数据引擎5.2 SA-V数据集 6 零样本实验6.1 视频任务6.1.1 提示视频分割6.1.2 半监督视频对象分割6.1.3 公平性评估 6.2 图像任务 7 与半监督VOS的最新技术的比较8 数据和模型消融8.1 数据消融8.2…

JavaSE篇之内部类和图书系统

1.内部类(类中类) 在Java中&#xff0c;将一个类定义在另一个类内部&#xff0c;前者称为内部类&#xff0c;后者称为外部类。 注意事项&#xff1a; 1. 1.静态内部类&#xff08;被static修饰的内部类&#xff09; 1.在静态内部类的方法中不能直接引用外部类的成员变量&…

手把手教你捏一个自己的Agent

01 前言 Modelscope AgentFabric是一个基于ModelScope-Agent的交互式智能体应用&#xff0c;用于方便地创建针对各种现实应用量身定制智能体&#xff0c;目前已经在生产级别落地。 AgentFabric围绕可插拔和可定制的LLM构建&#xff0c;并增强了指令执行、额外知识检索和利用…

Qt控制开发板的LED

Qt控制开发板的LED 使用开发板的IO接口进行控制是嵌入式中非常重要的一点&#xff0c;就像冯诺依曼原理说的一样&#xff0c;一个计算机最起码要有输入输出吧&#xff0c;我们有了信息的接收和处理&#xff0c;那我们就要有输出。 我们在开发板上一般都是使用开发板的GPIO接口…

Leetcode 旋转图像

解题思路&#xff1a; 转置矩阵&#xff1a;通过将矩阵的行列互换来实现转置操作。水平翻转矩阵&#xff1a;通过将每行的数据进行对称交换&#xff0c;从而完成90度旋转。 通过这两个步骤&#xff0c;矩阵就会顺时针旋转90度。 class Solution { public:void rotate(vector…