0

vuecli源码解析(3)

 2 years ago
source link: https://icodex.me/2022/01/23/vuecli%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%903/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

vuecli源码解析(3)

2022年1月23日 · One min read

image-20220122161800174

vue-cli-service作为第一个必然会被调用的plugin,其功能主要是生成项目模板文件,以及通过servebuild等命令进行开发环境server的启动和生产环境的构建打包等。下面分析其内部逻辑。

检查 Node 版本

vue-cli-service位于@vue/cli-service目录下,通过package.json找到其入口程序为bin/vue-cli-service.js,首先依旧是检查 Node 版本。

初始化Service实例

传入执行当前命令的目录,也就是创建项目的文件夹,来初始化Service实例。

image-20220122182531357

加载项目运行程序和webpack配置项

image-20220122183108440

resolvePlugins会从上层的commands以及config目录加载进来所有index.js文件。commands目录下包括开发环境执行程序serve.js以及生产环境打包build.js等,config目录包含webpack的配置程序,都是项目运行所需的程序,因为通过@vue/cli创建的项目不会暴露webpack等配置项,所以需要这些程序来执行。

这些程序被看做plugin,包含一个id作为标识符,和一个apply方法,需要执行的时候调用apply方法即可。

image-20220123135153677

然后还会对plugins进行排序。

serve.js

serve.js是开发环境下启动 webpack dev server 的程序,其返回的是一个函数,函数内部通过调用api.registerCommand传递了三个参数,那么serve.js通过plugin的方式注册,肯定会有执行的时候,见下文继续探索。

image-20220122184906777

并且导出的模块还有一个defaultModes对象,包含命令名称和环境变量参数的映射关系,这样Service实例内部可以通过defaultModes获取当前程序执行的环境。

image-20220122184932953

image-20220122190528586

build.js

build.js是生产环境的打包程序,则通过调用api.registerCommand传递build字符串等参数,以及暴露了production的环境变量。

image-20220123153348102

image-20220123153415916

css.js

config目录下的css.js为例,其通过api.chainWebpack来配置webpack

image-20220123200053836

注册命令行参数

初始化完Service实例,加载完项目所需要的所有执行程序,然后会执行run方法,run内部首先会走init方法。

image-20220122185844560

image-20220122190940124

加载env

init方法内部会加载指定环境的.env文件内部设置环境变量参数,这里使用了dotenvdotenv-expand这两个库来加载.env文件的环境变量到process.env中。

image-20220123153707199

image-20220123160135916

获取项目配置项

在加载了环境变量参数以后,会调用loadUserOptions方法,loadUserOptions内部会调用loadFileConfig获取项目内部的vue.config.js等形式的配置文件。

image-20220123160527552

然后用户项目配置项会传入loadedCallback函数内部,使用lodash.defaultsDeepvue-cli-service内部的默认配置合并。

image-20220123161123293

image-20220123160841575

注入PluginAPI实例

loadedCallback内部会调用每个pluginapply方法,传入PluginAPI的实例和当前项目的配置项作为参数。

image-20220123160950689

其中PluginAPI在初始化的时候传递了两个参数:

  • idplugin程序的名称
  • this:指向当前的Service实例

在构造函数内部初始化以后,Service实例会挂载在PluginAPI实例的service属性上。

image-20220123162103664

上文介绍到apply也就是serve.js等构建模块导出的函数,其接收两个参数:

  • apiPluginAPI的实例
  • options:项目的配置项

PluginAPI内部定义了一系列方法可以通过api来调用,其中api.registerCommand是往Service实例的commands上注册vue-cli-service的 CLI 命令参数名称serve,不过这里只是注册,并没有开始执行,所以到这里程序的目的只是将构建项目需要的程序加载进来,并且和命令行参数对应起来而已。

image-20220122184906777

image-20220123162213927

后面的话,如果在配置文件中包含chainWebpackwebpackConfig配置项也会挂载到Service实例的webpackChainFnswebpackRawConfigFns属性上。

组合webpack配置项

上文说到config目录下的程序会通过api.chainWebpack注册一些 webpack 的配置项,这些配置项会保存在Service实例的webpackChainFnswebpackRawConfigFns内部。

image-20220123200323198

执行程序

命令行参数现在和执行程序已经通过init方法关联起来了,接下来便是找到在 CLI 输入的命令参数对应的执行程序,然后执行。

接着看run方法内部的逻辑。这里通过this.commands找到了和命令行参数name对应的执行程序command,然后便调用command.fn这个方法,也就是serve.js内部传递的回调函数,也就是开发环境启动 webpack dev server 等操作。

image-20220123162926937


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK