原文链接:http://axuebin.com/articles/fe-solution/cli/desc.html,转载请联系

写在前面

提到初始化项目,那就必须提到脚手架这个名词,那为什么这篇文章的标题不是关于脚手架而是关于初始化项目呢?

脚手架这个名词来源于建筑工程领域,百度百科对其的解释是“脚手架是为了保证各施工过程顺利进行而搭设的工作平台”,也就是说脚手架为工人提供了施工的基础功能。将其引申到软件工程领域,又是什么含义呢?

  • 狭义上讲,脚手架是一个可以快速地使用配置好的工程模板初始化工程的工具,避免重复工作,为开发者提供便利;
  • 广义上讲,脚手架是一个完善的面向整个前端项目生命周期的工程解决方案,从初始化、开发调试到构建部署,都提供了一系列的工具或者规范,并且集成到一个“工具”中,开发者只需关心业务逻辑开发即可,这工具也可以称为“脚手架”。

由于完整的工程解决方案会涉及到大量的知识点,在这里就不展开说了。本文介绍的脚手架仅是狭义上的项目初始化。

为什么需要脚手架

现在大多数开发者已经习惯使用 vue-cli / create-react-app 等工具来快速初始化一个项目,不妨先看看前端项目初始化的一个发展历程:

  1. 远古时代。手动创建前端三件套:index.html/index.js/index.css,在 index.html 里分别引入 index.js 和 index.css
  2. 石器时代。将项目模板代码托管到 Git/SVN 上,使用的时候先手动将代码拉到本地,然后修改文件夹名以及项目中的配置
  3. 青铜时代。通过脚本,自动化做了一些事情:拉取项目模板、配置项目信息等
  4. 蒸汽时代。形成一套完整的命令行工具,比如 vue-cli/ create-react-app 等
  5. 工业时代。在 cra/vue-cli 的基础上定制个性能力,接入自定义模板、自动化 Git 流程、数据采集等
  6. 现代。脚手架已经跳出终端(命令行),有了可视化、WebIDE 等方案,通过更为方便的交互即可完成项目的初始化

从这样一个发展历程可以看出,脚手架解决的核心问题就是 —— 帮助开发者更方便地初始化项目,这也就是为什么需要脚手架。总结来说,脚手架最重要的作用有两点:

  1. 提高效率。之前初始化一个可用的项目可能需要 1 个小时甚至更久,到如今只需要敲个命令或者点下鼠标然后伸个懒腰就搞定了
  2. 降低成本。比如创建文件、配置项目信息等都是重复工作,开发者没必要花精力在这些可以自动化的事情上

在完整的前端工程体系中,脚手架起到至关重要的作用。

接下来介绍几个目前常用的的、你一定见过的几种脚手架方案,你是否有思考过它是如何实现的呢?

常见脚手架底层方案

目前,常见的脚手架底层都会依赖两种方案:使用 download-git-repo 来下载模板代码,以及使用 Yeoman 来作为脚手架的一个核心能力进行扩展。

download-git-repo

通过 download-git-repo 这个 npm 包可以实现 git 仓库的拉取,支持 GitHub、GitLab 等。基于这个 npm 包,我们可以写一个简单的脚本来实现简易的模板下载功能。

关于 download-git-repo 的用法在这里就不展开了,感兴趣的可以自己试试看。

Yeoman Generator

Yeoman 是一个较早就出现的脚手架工具,它的第一次发布已经是在 8 年前,那时候我还没开始学习前端。很多人都说,前端技术太杂,各种技术更新太快,这句话也没什么问题,前端技术随着移动互联网的爆发也迎来了百花齐放的时代,一些技术在潮流中被后浪就拍没了。Yeoman 历经 8 年还存活着,这是为什么呢?不急,待我们剖析了 Yeoman 的原理之后,你会觉得它确实可以在现在的前端工程化中占有一席之地。

Yeoman is a generic scaffolding system allowing the creation of any kind of app.

将 Yeoman 放在了「常见脚手架底层方案」,是因为 Yeoman 它并不能直接初始化项目所需的文件,它是一个脚手架系统,开发者们使用 Yeoman 提供的 API 可以定制任意脚手架,完全开放、自由的,扩展性极强。

可以理解 Yeoman 提供一个插件体系,开发者可以自定开发插件来使用 Yeoman 的能力,这个“插件”在 Yeoman 中称为 generators,所有代码生成的能力都由 generators 提供。

是不是充满了想象力?这个包的存在,给脚手架的实现提供了无限可能性。

常见脚手架集成方案

目前对于前端开发者来说,社区上比较常用的两个脚手架是 Vue CLI 和 Create React App。

Vue CLI

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供了终端命令行工具、零配置脚手架、插件体系、图形化管理界面等。

核心思想

Vue CLI 的核心原理主要有两部分:

  1. 预设管理。在 CLI 内部通过统一的实例对 prompt(终端交互)和 preset(预设)进行管理,交互之前存在互联关联层层递进的关系,在初始化的时候,这些用于终端交互的配置就初始化在内存中,根据用户的选择触发不同的逻辑。
  2. 灵活的插件系统。在 Vue CLI 中使用了一套基于插件的架构,将 CLI 的逻辑和生成代码的逻辑解耦,通过不同的插件去修改文件内容和配置,生成最终的代码。

Vue CLI 同时还提供了图形化界面对项目进行初始化、管理,这也是和 Create React App 等 CLI 不同的地方之一。

自定义模板

Vue CLI 官方初始化模板只有一个,内置在 @vue/cli-service  核心插件中,CLI 提供的 api.render('./template')  方法会将模板通过 EJS 模板引擎渲染到内存中,最终在 CLI 中通过 Node 的写文件操作写到本地目录中。

如果开发者需要自定义模板,需要开发一个插件来创建新的模板,在插件中编写相关生成代码的逻辑。

源码解析

如果你想了解更多关于 Vue CLI 的细节,可以阅读 Vue CLI 是如何实现的 -- 终端命令行工具篇

Create React App

Create React App 是 React  官方创建应用的脚手架。

核心思想

Create React App 的核心思想我理解主要是:

  1. 脚手架核心功能中心化:使用 npx 保证每次用户使用的都是最新版本,方便功能的升级
  2. 模板去中心化:方便地进行模板管理,这样也允许用户自定义模板
  3. 脚手架逻辑和初始化代码逻辑分离:CLI 中只负责核心依赖、模板的安装和脚手架的核心功能,而初始化代码的逻辑在 react-scripts 包里执行

自定义模板

使用 Create React App 时,可以传入 template 参数使用自定义模板:

npx create-react-app my-app --template [template-name]

如果不传,则使用 cra-template 这个默认模板。

比如, --template typescript 就会使用 cra-template-typescript 这个 TypeScript 的模板。

用户可以按照模板规范发布自定义模板,并且发布到 npm 上。最主要的一个规范是,它的 npm 包名是 cra-template-xxx

源码解析

如果你想了解更多关于 create-react-app 的细节,可以阅读 create react app 核心思路分析

总结

无论是 create-react-app 还是 Vue CLI,在设计的时候都会尽量考虑插件机制,将能力开放出去给开发者再将功能集成到 CLI。除了有利于自身的功能迭代之外,对于社区开发者来说,都具备了足够的开放性和扩展性。

并且可以看到,这两个脚手架已经抛开了对 git 的依赖,将模板的代码通过 npm 进行管理,并且借助一些类似 ejs 等的模板引擎能力,对静态模板中的代码进行渲染替换,模板代码可以更加多样化。

常见现代方案

到了“工业时代”,脚手架不仅仅是在 CLI 中通过 init  等命令生成一个代码目录这么单调了,趋势逐渐向平台化发展,并且枯燥单调的终端界面也在往 UI 图形化界面过渡。

图形化界面:Vue UI

先来看一下图形化界面,上文提到的 Vue CLI 就提供了对应的图形化界面来对项目进行管理。

相比于 CLI 枯燥的界面和交互单一,UI 图形化界面有更丰富的交互形式,对于现代开发者来说美观。当然,它不是简单的一个 web 界面,你可以先使用 vue ui  体验一下。

这是 Vue UI 的整体架构图:

我们将 Vue UI 看作运行在浏览器的客户端,而本地终端起了一个 Node 服务当作是服务端。通过插件机制,在插件中开发者可以调用插件 API 做一些事情,也可以完成客户端和服务端的通信。比如在图形化界面上初始化了项目之后,终端会收到事情“触发”,然后将项目代码初始化到本地文件系统中。

参考链接:https://cli.vuejs.org/guide/creating-a-project.html#using-the-gui

IDE 集成编辑器:小程序开发者工具

除了 UI 图形界面之外,如今初始化项目的能力也常被集成在 IDE 中,比如小程序开发工具。

打开支付宝小程序开发者工具,就可以直接根据需要选择一个功能完备的模板初始化项目,比如开发者想要在支付宝小程序中体验 Serverless 的功能,就可以直接选中 Serverless 入门 DEMO 这个模板创建项目。

项目初始化之后,开发者也是在这个 IDE 中进行开发、构建、发布,在整个开发链路中,都不会有切换工具带来的负担,对于开发者而言,开发体验是非常棒的。

参考链接:https://opendocs.alipay.com/mini/ide/start-page

VSCode 插件:Iceworks

目前很多前端开发者都在用 VSCode 整个编辑器,如果让开发者为了一些提效的能力去放弃常用、熟悉的编辑器,也不是一个很好的选择。VSCode 插件作为一个轻量级的接入方式,也可以让开发者在 VSCode 中使用初始化项目等功能。

比如,Iceworks 就是一款可视化智能研发助手,帮助开发者快速使用可视化和智能化的能力进行应用开发。

在 VSCode 中安装了 Iceworks 插件之后,就有图形化界面引导创建应用,点击完成之后就直接在本地生成项目文件了。在这之后,就是正常地使用 VSCode 进行开发。

参考链接:https://ice.work/docs/guide/gui-start

总结

这篇文章主要是介绍前端工程化中初始化项目的部分,CLI 章节对 Vue CLI 和 Create React App 进行了源码解析,其它章节没有展开介绍,感兴趣的朋友可以深入了解一下。

现代 CLI 和 GUI 方案指南的更多相关文章

  1. 良好的GUI设计指南

    一.设计指南 摘自:<需求分析与系统设计(第3版)> 7.1.2. 1. 用户控制 用户事件(菜单动作.鼠标点击.屏幕光标移动等)打开GUI窗口或调用程序:程序执行需要反馈到用户. 2.  ...

  2. 什么是CLI、GUI

    就是命令行界面command-line interface,也有人称之为字符用户界面(CUI). 通常认为,命令行界面(CLI)没有图形用户界面(GUI)那么方便用户操作. 因为,命令行界面的软件通常 ...

  3. jquery/vue/react前端多语言国际化翻译方案指南

    ❝ 本文章共3470字,预计阅读时间5-10分钟. ❞ 国际化-前言 每个开发者能希望编写的程序可以让全世界的用户使用,它要求从产品中抽离所有地域语言,国家/地区和文化相关的元素.换种说法,「应用程序 ...

  4. 快速上手最新的 Vue CLI 3

    翻译:疯狂的技术宅 原文:blog.logrocket.com/getting-sta- 概要:本文将指导你快速上手 Vue CLI 3,包括最新的用户图形界面和即时原型制作功能的使用步骤. 介绍 尤 ...

  5. Atitit.现在的常用gui技术与gui技术趋势评价总结

    Atitit.现在的常用gui技术与gui技术趋势评价总结 1. Gui俩种分类:  native 和 dsl 和 script1 2. 最好的跨平台gui技术h51 2.1. 几大技术体系(java ...

  6. python图形界面(GUI)设计

    不要问我为什么要用 python 来做这种事,我回到“高兴咋地”也不是不可以,总之好奇有没有好的解决方案.逛了一圈下来,总体上来说,python 图形界面有以下几个可行度比较高的解决方案. 1. py ...

  7. bootloader (run in CLI or Qt-GUI mode)

    1.PC端 https://github.com/cidadao/efm32_loader http://theramblingness.com/2015/07/16/a-gui-and-cli-ut ...

  8. ArduinoYun教程之OpenWrt-Yun与CLI配置Arduino Yun

    ArduinoYun教程之OpenWrt-Yun与CLI配置Arduino Yun OpenWrt-Yun OpenWrt-Yun是基于OpenWrt的一个Linux发行版.有所耳闻的读者应该听说他是 ...

  9. 嵌入式系统WinCE下应用程序GUI界面开发【转】

    嵌入式系统WinCE下应用程序GUI界面开发 ByToradex 秦海 本文旨在介绍嵌入式系统在Wince下进行GUI应用程序开发可以选择的不同GUI开发框架(Framework),目前最常用的几种方 ...

随机推荐

  1. JavaScript中判断对象是否属于Array类型的4种方法及其背后的原理与局限性

    前言 毫无疑问,Array.isArray是现如今JavaScript中判断对象是否属于Array类型的首选,但是我认为了解本文其余的方法及其背后的原理与局限性也是很有必要的,因为在JavaScrip ...

  2. linux下安装mysql8.0.x步骤

    1.下载mysql mysql官网:https://dev.mysql.com/downloads/mysql/ 将下载的mysql上传打linux 2.解压并重命名 [root@rsyncClien ...

  3. Java自学第6期——Collection、Map、迭代器、泛型、可变参数、集合工具类、集合数据结构、Debug

    集合:集合是java中提供的一种容器,可以用来存储多个数据. 集合和数组既然都是容器,它们有啥区别呢? 数组的长度是固定的.集合的长度是可变的. 数组中存储的是同一类型的元素,可以存储基本数据类型值. ...

  4. springCloud服务流程

    springCloud的服务流程:消费者调用生产者 1.通过接口化的请求调用(指定接口的服务名字和服务地址)只是做定义,并没有真正做到. 2.Feign组件,远程去注册中心找到服务的名字和服务的地址然 ...

  5. mysql锁——innodb的行级锁

    [前言]数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则.MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎所针对的应 ...

  6. python+unittest+ddt数据驱动进行接口自动化测试

    所谓数据驱动测试,简单的理解为数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变.通过使用数据驱动测试的方法,可以在需要验证多组数据测试场景中,使用外部数据源实现对输入输出与期望值的参数化,避 ...

  7. 在不使用外延层的同轴半绝缘衬底材料上制作4H-SIC横向双重注入金属氧化物半导体场效应晶体管

    在不使用外延层的同轴半绝缘衬底材料上制作4H-SIC横向双重注入金属氧化物半导体场效应晶体管 杂志:日本应用物理杂志   在不使用外延层在同轴的半绝缘SIC衬底上制作4H-SIC横向双重注入金属氧化物 ...

  8. HDOJ-4725(Dijikstra算法+拆点求最短路)

    The Shortest Path in Nya Graph HDOJ-4725 这题是关于最短路的问题,但是和常规的最短路有点不同的就是这里多了层次这一结构. 为了解决这一问题可以把每一层抽象或者划 ...

  9. python基础学习之类的属性 增删改查

    类中的属性如何在类外部使用代码进行增删改查呢 增加.改变: setattr内置函数以及 __setattr__魔法方法 class A: aaa = '疏楼龙宿' a = A() setattr(a, ...

  10. android消息线程和消息队列

    基于消息队列的线程通信:           消息队列与线程循环            MessageQueue:           利用链表来管理消息.                  Mess ...