脚手架入门与实践

脚手架简介

脚手架本质是一个操作系统的客户端,它是通过命令行执行。最常用的脚手架有:npm、vue-cli、create-react-app、webpack-cli等。

实际工作中,我们往往需要借助脚手架来做各种流程的自动化,可以帮助我们开发各种提效工具,帮助企业大幅度节约研发成本。

脚手架命令分析

我们拿vue的脚手架举例:

bash 复制代码
vue create vue-test-project

上面这条命令由 3 个部分组成:

  • 主命令: vue
  • command: create
  • command 的 param: vue-test-project

它表示创建一个 vue 项目,项目的名称为vue-test-project。 我们也可以携带参数:

bash 复制代码
vue create vue-test-project --force

--force 叫做 option,用来辅助脚手架确认在特定场景下用户的选择。

脚手架执行原理

简单总结为以下几点:

  • 在终端输入vue-test-project
  • 终端解析出 vue 命令,并在环境变量中找到 vue 命令
  • 终端根据 vue 命令链接到实际文件 vue.js
  • 终端利用 node 执行 vue.js
  • vue.js 解析 command / options , 并执行 command
  • 执行完毕,退出执行

什么是 Bash 和 CLI

这里简单介绍一下:

  • Shell 是操作系统提供的接口程序,用于接收用户输入的命令,交给操作系统内核执行并接收响应结果
  • Bash 是 Shell 的一个实现,用于执行用户输入的命令
  • CLI 是 Bash 的运行环境,CLI 接收用户键盘输入,交给 Bash 执行,并将程序处理结果结果以文本形式进行显示

为什么需要脚手架框架

简单总结就是包括以下两点:

  • 提升开发效率,大幅提升脚手架命令创建、修改的速度
  • 简化开发过程,大幅提升代码的可读性和可维护性

脚手架开发流程

脚手架创建

使用npm init初始化项目。

bash 复制代码
npm init

脚手架开发

参数解析:可以使用 commander.js 这个库来解析用户的命令。

脚手架调试

本地调试

bash 复制代码
npm link

npm link:将当前项目链接到 node 全局 node_modules 中作为一个库文件,并解析 bin 配置创建可执行文件。

脚手架发布

bash 复制代码
npm publish

实现下载代码脚手架

目标:实现一个可交互的下载代码脚手架。

项目目录

  • bin/cli.js:脚手架入口文件
  • lib/core
    • action.js:执行操作文件
    • download.js:执行文件下载
    • help.js:帮助命令
    • myCommander.js:命令文件
  • config.js:配置文件

安装依赖

bash 复制代码
npm i chalk
npm i commander
npm i download-git-repo
npm i inquirer
npm i ora
  • chalk:是一个可以修改终端输出字符样式的 npm 包。
  • commander:是一个命令行框架,提供了用户命令行输入和参数解析功能。
  • download-git-repo:从node下载并提取git存储库。
  • inquirer:命令行提示器。
  • ora:loading状态。

项目开发

代码比较简单,大家可以按照项目目录实现一遍。

package.json文件

这里需要强调bin命令,它的作用就是去执行bin/cli.js文件。

javascript 复制代码
// package.json

{
  "name": "cli",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "bin": {
    "cli": "bin/cli.js"  // 执行bin/cli.js
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "chalk": "^4.1.2",
    "commander": "^9.1.0",
    "download-git-repo": "^3.0.2",
    "inquirer": "^8.2.1",
    "ora": "^5.4.1"
  }
}

cli文件

加入 #! /usr/bin/env node 的目的是系统看到这一行的时候,首先会到env设置里查找node的安装路径,再调用对应路径下的解释器程序完成操作。

javascript 复制代码
// bin/cli.js

#! /usr/bin/env node

const { program } = require('commander');
const myhelp = require('../lib/core/help');
myhelp(program); 

const myCommander = require('../lib/core/myCommander');
myCommander(program); // 执行命令
program.parse(process.argv); // 解析参数

help文件

创建提示命令:

javascript 复制代码
// lib/core/help.js

const help = function(program){
  program.option('-f --framwork <framwork>','设置框架')
}
module.exports = help

myCommander文件

执行命令文件:

javascript 复制代码
// lib/core/myCommander.js

const myaction = require('./action')

const myCommander = function (program) {
  program
    .command('create <project> [other...]') // 命令
    .alias('crt') // 别名
    .description('创建项目')
    .action(myaction) // 执行
}

module.exports = myCommander

action文件

javascript 复制代码
// lib/core/action.js

var inquirer = require('inquirer')
var config = require('../../config')
var downloadFun = require('./download')
const myAction = async (project) => {
  
  const answer = await inquirer.prompt([
    {
      type: 'list',
      name: 'framwork',
      choices: config.framwork,
      message: '请选择你所使用的框架'
    }
  ])
  
  // 下载代码模板
  downloadFun(config.foramworkUrl[answer.framwork],project)
}

module.exports = myAction

download文件

选择模板,下载对应的代码文件。

javascript 复制代码
// lib/core/download.js
const download = require('download-git-repo')
const ora = require('ora')
const chalk = require('chalk')
const downloadFun = function (url, project) {
  const spinner = ora().start()
  spinner.text = '代码正在下载......'
  download('direct:' + url, project, { clone: true }, (err) => {
    if (!err) {
      spinner.succeed('代码下载成功')
      console.log(chalk.blue.bold('Done!'), chalk.bold('you run:'));
      console.log('cd ' + project);
      console.log('npm install ');
      console.log('npm run dev ');
    } else {
      spinner.fail('代码下载失败')
    }
  })
}

module.exports = downloadFun

config文件

配置文件地址:

javascript 复制代码
module.exports = {
  // 可选择的框架
  framwork: ['umi', 'other'],
  // 框架对应的下载地址
  foramworkUrl: {
    umi: 'https://gitee.com/mirrors/umi.git',
    other: 'xxx', // 自己添加
  },
};

本地使用

挂载全局

cd到项目目录,执行 npm link:

bash 复制代码
npm link

可以看到将当前项目链接到 node 全局 node_modules 中。

安装依赖

bash 复制代码
npm install

执行脚手架命令

bash 复制代码
cli create umi

实现效果

总结

至此,一个简单的工程脚手架就完成了。可以继续关注此专栏,之后会增加功能完善的脚手架。

相关推荐
普郎特8 分钟前
"不再迷惑!用'血缘关系'彻底搞懂JavaScript原型链机制"
前端·javascript
可观测性用观测云17 分钟前
前端错误可观测最佳实践
前端
恋猫de小郭18 分钟前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter
一枚前端小能手39 分钟前
「周更第3期」实用JS库推荐:Lodash
前端·javascript
艾小码39 分钟前
Vue组件到底怎么定义?全局注册和局部注册,我踩过的坑你别再踩了!
前端·javascript·vue.js
Cyan_RA91 小时前
计算机网络面试题 — TCP连接如何确保可靠性?
前端·后端·面试
谢尔登1 小时前
【CSS】层叠上下文和z-index
前端·css
鹏多多1 小时前
前端复制功能的高效解决方案:copy-to-clipboard详解
前端·javascript
AryaNimbus1 小时前
你不知道的 Cursor系列(三):再也不用死记硬背 Linux 命令,终端 Cmd+K 来帮你!
前端·ai编程·cursor
uhakadotcom1 小时前
Rollup 从0到1:TypeScript打包完全指南
前端·javascript·面试