grunt源码解析:整体运行机制&grunt-cli源码解析

前端的童鞋对grunt应该不陌生,前面也陆陆续续的写了几篇grunt入门的文章。本篇文章会更进一步,对grunt的源码进行分析。文章大体内容内容如下:

  1. grunt整体设计概览
  2. grunt-cli源码分析
  3. grunt-cli模块概览
  4. grunt-cli源码分析
  5. 写在后面

grunt整体设计概览

grunt主要由三部分组成。其中,grunt-cli是本文的讲解重点

  1. grunt-cli:命令行工具,调用本地安装的grunt来运行任务,全局安装。
  2. grunt:本地grunt,一般安装在项目根目录下。主要作用是读取插件配置,调用指定的grunt插件。
  3. grunt插件:完成具体的构建任务。

grunt运行机制

抛开代码细节,grunt运行的整体流程如下。接下来,我们就会对红框部分,grunt-cli的源码进行进一步的探讨。

grunt-cli源码分析

grunt-cli/packge.json里可以看到,主入口文件是 bin/grunt。接下来,我们就分析下bin/grunt.js的源码。

"bin": {
    "grunt": "bin/grunt"
},

grunt-cli源码概览

同样,我们先通过一个简单的流程图看下这个文件究竟做了什么事情。从下图可以看到,主要包含三个逻辑分支。

  1. 运行任务:主要的分支,用绿色标出,比如运行grunt copy就会进入这个分支
  2. 信息查看:右侧的一堆if/else分支,如运行grunt --version就会进入这个分支(还有其他如help等没列出来)
  3. 异常处理:非上面两种情况,异常退出。

查看信息

如果命令行中包含--completion--version

  • 如果有--completion,输出自动完成信息,程序退出
  • 如果有--version,输出版本信息,程序退出

运行任务

  1. 命令行中是否有--gruntfile--base

    • 都有:优先将basedir设置为gruntfile指定的路径
    • 只有gruntfilebase:将basedir设置为basegruntfile指定的路径
  2. 根据basedir找到当前项目的grunt,并运行指定任务

异常处理

如果没有包含--completion--version,当前项目下也没有安装grunt,异常退出。

grunt-cli模块概览

下图为grunt-cli的整体目录机构,相对比较简单。这里做下介绍

  1. bin/grunt:主入口文件,调用其他模块来完成工作。
  2. lib/*:被bin/grunt调用,主要有如下几个模块
    • cli.js:分析、处理命令行参数。
    • completion.js:处理自动完成信息。
    • info:打印版本、帮助信息等。

grunt-cli源码分析

首先,引入组件的依赖模块

// Especially badass external libs.
var findup = require(‘findup-sync‘);  // 文件查找
var resolve = require(‘resolve‘).sync;  // 路径解析

// Internal libs.
var options = require(‘../lib/cli‘).options;  // 解析后的命令行参数
var completion = require(‘../lib/completion‘);  // 自动完成
var info = require(‘../lib/info‘);  // 版本信息等
var path = require(‘path‘);

var basedir = process.cwd();
var gruntpath;

然后,根据命令行参数,决定是否要打印版本信息、自动完成信息,还是设置当前的工作路径(basedir)

// Do stuff based on CLI options.
if (‘completion‘ in options) {
  completion.print(options.completion); // 打印自动完成信息,程序退出
} else if (options.version) {
  info.version(); // 打印版本信息(在本地grunt里会退出)
} else if (options.base && !options.gruntfile) {
  basedir = path.resolve(options.base); // 根据 base 设置 basedir
} else if (options.gruntfile) { // 根据 gruntfile 设置 basedir
  basedir = path.resolve(path.dirname(options.gruntfile));
}

最后的考验,如果能找到本地grunt,就进入最后一步;如果找不到,很有可能就异常退出了。

try {
  // 得到当前目录的本地grunt路径(grunt/lib/grunt.js)
  gruntpath = resolve(‘grunt‘, {basedir: basedir});  // 得到的是类似这样的路径 /Users/usename/Documents/code/edu_proj/trunk/htdocs/ke.qq.com/node_modules/grunt/lib/grunt.js
} catch (ex) {
  gruntpath = findup(‘lib/grunt.js‘);  // 有可能当前在项目的子目录里,逐级往上查找,直到找到 grunt
  // No grunt install found!
  if (!gruntpath) { // 找不到grunt,悲剧了
    if (options.version) { process.exit(); }  // 打印版本信息,退出
    if (options.help) { info.help(); }  // 打印帮助信息
    info.fatal(‘Unable to find local grunt.‘, 99);  // 打印错误日志,并异常退出
  }
}

恭喜,来到这一步,可以愉快地运行构建任务了。

// Everything looks good. Require local grunt and run it.
require(gruntpath).cli();  // 找到 本地grunt了,开始运行 .cli 是local grunt的方法

写在后面

本文对构建工具grunt的整体设计、运行机制,以及grunt-cli的源码进行了较为深入的分析。后续会对本地grunt的源码进行剖析,敬请期待。如有错漏,请指出。有任何疑问也可以在下面留言 :)

grunt源码解析:整体运行机制&grunt-cli源码解析

时间: 2024-08-19 11:01:58

grunt源码解析:整体运行机制&grunt-cli源码解析的相关文章

ASP.NET的学习之asp.net整体运行机制

1.浏览器向服务器发送请求报文,服务器端的软件比如是IIS,接受请求 2.IIS通过aspnet_isapi.dll 这个程序集来请求FrameWork中的ASP.Net框架,这是对于集成模式 3.进入框架中,首先调用IsapiRunTime 的ProcessRequest(); 4.然后再调用HTTPRuntime的 ProcessRequest(),在方法中创建Http上下文对象 HttpContext, 这个上下文对象很重要,因为在下面调用管道事件时,他是负责通信的. 5.然后再通过Htt

ASP.NET请求管道、应用程序生命周期、整体运行机制

我们知道在ASP.NET中,若要对ASP.NET应用程序进行 初始化并使它处理请求,必须执行一些处理步骤,熟悉应用程序生命周期非常重要,这样才能在适当的生命周期阶段编写代码,达到预期的效果.永远不要做只会拖 控件的.NET程序员,Never!那么你就必须懂ASP.NET应用程序生命周期,懂ASP.NET页面生命周期,懂ASP.NET 服务器控件原理.接下来,我们一起来看看 可以先看一下先导篇 [深入ASP.NET原理系列]--ASP.NET请求管道对Asp.Net WebForm和Asp.Net

源码深度解析SpringMvc请求运行机制

本文依赖的是springmvc4.0.5.RELEASE,通过源码深度解析了解springMvc的请求运行机制.通过源码我们可以知道从客户端发送一个URL请求给springMvc开始,到返回数据给客户端期间是怎么运转的. 1.用户请求处理过程: 1.用户发送请求时会先从DispathcherServler的doService方法开始,在该方法中会将ApplicationContext.localeResolver.themeResolver等对象添加到request中,紧接着就是调用doDisp

源码深度解析SpringMvc请求运行机制(转)

源码深度解析SpringMvc请求运行机制 本文依赖的是springmvc4.0.5.RELEASE,通过源码深度解析了解springMvc的请求运行机制.通过源码我们可以知道从客户端发送一个URL请求给springMvc开始,到返回数据给客户端期间是怎么运转的. 1.用户请求处理过程: 1.用户发送请求时会先从DispathcherServler的doService方法开始,在该方法中会将ApplicationContext.localeResolver.themeResolver等对象添加到

PULL解析XML的运行机制详解

PULL解析简单易上手,基本上看一遍,基本上就会解析啦,但总是感觉对PULL解析的运行机制不是很了解,就总结了以下事件驱动到底是怎么执行的.. PULL: Android内置了PULL解析器.PULL解析器与SAX解析器类似,它提供了类似的事件,例如,开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发事件.每一种事件将作为数值代码被传送,因此使用一个switch来对感兴趣的事件进行处理. 这也是我最喜欢的方法,简单好用. 下面将对解析过程进行详细介绍,它到底是怎么运行

ASP.NET 运行机制续(完结)

上一篇说到applicationInstance会执行一些列的事件.下面是我在msdn上找到有关asp.net程序生命周期相关的描述及图片 声明周期的起始 ASP.NET 应用程序的生命周期以浏览器向 Web 服务器(对于 ASP.NET 应用程序,通常为 IIS)发送请求为起点. ASP.NET 是 Web 服务器下的 ISAPI 扩展. Web 服务器接收到请求时,会对所请求的文件的文件扩展名进行检查,确定应由哪个 ISAPI 扩展处理该请求,然后将该请求传递给合适的 ISAPI 扩展. A

ASP.NET运行机制原理 ---浏览器与IIS的交互过程 自己学习 网上查了下别人写的总结的很好 就转过来了 和自己写的还好里嘻嘻

一.浏览器和服务器的交互原理 (一).浏览器和服务器交互的简单描述: 1.通俗描述:我们平时通过浏览器来访问网站,其实就相当于你通过浏览器去访问一台电脑上访问文件一样,只不过浏览器的访问请求是由被访问的电脑上的一个 WEB服务器软件来接收处理,它会分析接收到的请求信息,从而按照请求信息来找到服务器电脑上的文件,经过处理,最终将生成的内容发回到浏览器. 简单的说就是:由浏览器生成一条“命令”,通过互联网发给另一台电脑的某个软件(服务器软件):服务器软件接收到“命令”,就分析理解这个“命令”,然后按

[Spark內核] 第42课:Spark Broadcast内幕解密:Broadcast运行机制彻底解密、Broadcast源码解析、Broadcast最佳实践

本课主题 Broadcast 运行原理图 Broadcast 源码解析 Broadcast 运行原理图 Broadcast 就是将数据从一个节点发送到其他的节点上; 例如 Driver 上有一张表,而 Executor 中的每个并行执行的Task (100万个Task) 都要查询这张表的话,那我们通过 Broadcast 的方式就只需要往每个Executor 把这张表发送一次就行了,Executor 中的每个运行的 Task 查询这张唯一的表,而不是每次执行的时候都从 Driver 中获得这张表

Flink 源码解析 —— 深度解析 Flink 序列化机制

Flink 序列化机制 https://t.zsxq.com/JaQfeMf 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭建 Flink 1.6.0 环境并构建运行简单程序入门 3.Flink 从0到1学习 -- Flink 配置文件详解 4.Flink 从0到1学习 -- Data Source 介绍 5.Flink 从0到1学习 -- 如何自定义 Data Source ? 6.Flink 从0到1学习 -- Da