关于cli工具和脚手架的原理(菜鸟前端学习笔记)

问题


脚手架,CLI

  1. 脚手架是一类快速形成工程化目录的工具(业务类型),如:yeoman, @vue/cli, create-react-app.
  2. CLI(command-line-interface, 缩写:CLI)(效率工具), 如:webpack, es-lint, json-server

平常开发中经常会用到如上熟悉的脚手架,cli工具,那么这些工具,工具是如何实现的呢?原理是什么呢?


git源码浏览

  • @vue/cli为例,通过npmjs,github找到源码。
  • package.json中,查找dependencies, 程序入口
  • 浏览@vue/cli的代码工程化结构

话不多说,按照咱们的想法,先去github,vue/cli的工程上,瞅一瞅源码。对着package.json一阵观看:

 "devDependencies": {
    "@babel/core": "^7.9.0",
    "@vue/eslint-config-airbnb": "^5.0.2",
    "@vue/eslint-config-prettier": "^6.0.0",
    "@vue/eslint-config-standard": "^5.1.2",
    "@vue/eslint-config-typescript": "^5.0.2",
    "@vuepress/plugin-pwa": "^1.4.0",
    "@vuepress/theme-vue": "^1.4.0",
    "@typescript-eslint/eslint-plugin": "^2.26.0",
    "@typescript-eslint/parser": "^2.26.0",
    "babel-core": "7.0.0-bridge.0",
    "babel-eslint": "^10.1.0",
    "babel-jest": "^24.9.0",
    "chromedriver": "^80.0.1",
    "debug": "^4.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-graphql": "^3.1.0",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettier": "^3.1.1",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^6.2.2",
    "eslint-plugin-vue-libs": "^4.0.0",
    "execa": "^1.0.0",
    "geckodriver": "^1.19.1",
    "globby": "^9.2.0",
    "graphql": "^14.6.0",
    "http-server": "^0.12.1",
    "inquirer": "^7.1.0",
    "jest": "^24.9.0",
    "lerna": "^3.19.0",
    "lerna-changelog": "^0.8.3",
    "lint-staged": "^9.5.0",
    "memfs": "^3.1.2",
    "minimist": "^1.2.5",
    "prettier": ">= 1.13.0",
    "request": "^2.88.2",
    "request-promise-native": "^1.0.8",
    "rimraf": "^3.0.2",
    "semver": "^6.1.0",
    "typescript": "~3.8.3",
    "vuepress": "^1.3.0",
    "webpack": "^4.0.0",
    "yorkie": "^2.0.0"
  },

嗯,里面有许多我们平常写项目也会经常用到的依赖,不过也有些我一点都不认识的,当对这些不熟悉的依赖中有几个典型的可以介绍一下,比如:execainquirervuepress

  • execa:是一个js操作shell的工具,是很好的子进程管理工具;
  • inquirer: 是一个用户与命令行交互的工具,例如,我们在使用@vue/cli创建项目的时候,会有一些选择配置的交互,大概就是用这个实现的;
  • vuepress: 适用于发布项目的技术文档,静态网页生成器

当然这些都不是vue/cli整个项目的部分依赖,我们再去找找,项目的入口文件,我们点到项目的packages目录中,会看到一堆目录,找到我们的cli文件夹,点进去,看看package.json瞅瞅;

{
  "name": "@vue/cli",
  "version": "4.3.1",
  "description": "Command line interface for rapid Vue.js development",
  "bin": {
    "vue": "bin/vue.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/vuejs/vue-cli.git",
    "directory": "packages/@vue/cli"
  },
  "keywords": [
    "vue",
    "cli"
  ],
  "author": "Evan You",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/vuejs/vue-cli/issues"
  },
  "homepage": "https://cli.vuejs.org/",
  "publishConfig": {
    "access": "public"
  },
  "dependencies": {
    "@vue/cli-shared-utils": "^4.3.1",
    "@vue/cli-ui": "^4.3.1",
    "@vue/cli-ui-addon-webpack": "^4.3.1",
    "@vue/cli-ui-addon-widgets": "^4.3.1",
    "boxen": "^4.1.0",
    "cmd-shim": "^3.0.3",
    "commander": "^2.20.0",
    "debug": "^4.1.0",
    "deepmerge": "^4.2.2",
    "download-git-repo": "^3.0.2",
    "ejs": "^2.7.1",
    "envinfo": "^7.5.0",
    "fs-extra": "^7.0.1",
    "globby": "^9.2.0",
    "import-global": "^0.1.0",
    "inquirer": "^7.1.0",
    "isbinaryfile": "^4.0.5",
    "javascript-stringify": "^1.6.0",
    "js-yaml": "^3.13.1",
    "jscodeshift": "^0.7.0",
    "leven": "^3.1.0",
    "lodash.clonedeep": "^4.5.0",
    "lru-cache": "^5.1.1",
    "minimist": "^1.2.5",
    "recast": "^0.18.8",
    "resolve": "^1.15.1",
    "shortid": "^2.2.15",
    "slash": "^3.0.0",
    "validate-npm-package-name": "^3.0.0",
    "vue": "^2.6.11",
    "vue-jscodeshift-adapter": "^2.0.2",
    "yaml-front-matter": "^3.4.1"
  },
  "engines": {
    "node": ">=8.9"
  }
}

可以看到项目的入口文件是bin目录下的vue.js,稍后我们进去瞅瞅,看看用到的这些依赖,发现了一个commander, 具体的用处可以点开链接去看看。总而言之,就是node.js命令行接口的解决工具。最后,咱去看看vue.js,代码就不贴了,利用一系列的依赖来实现了用户与命令行的整个交互流程,还有一些复杂项目包管理配置操作,最终实现了脚手架快速创建项目的过程。

总结原理

  • commander获取用户传参
  • inquirer与用户进行交互,获取用户输入选项
  • bin执行文件,cli命令的入口。

后续会跟随学习,进一步更新学习的笔记,最终实现一个简易的脚手架工具。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,123评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,031评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,723评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,357评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,412评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,760评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,904评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,672评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,118评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,456评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,599评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,264评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,857评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,731评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,956评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,286评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,465评论 2 348

推荐阅读更多精彩内容