脚手架入门与实践

脚手架简介

脚手架本质是一个操作系统的客户端,它是通过命令行执行。最常用的脚手架有: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

实现效果

总结

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

相关推荐
掘金挖土21 分钟前
前端手摸手跑路之 AI 应用开发(三)
前端·后端
计算机魔术师37 分钟前
OpenAI 宣称破解千禧年难题,数学家却说是「反例搜索」?
前端
志尊宝39 分钟前
Vue3 零基础每日笔记(015):条件渲染 v-if 与 v-show——控制 DOM 生死还是控制显隐
前端·vue.js·笔记
掘金者阿豪1 小时前
OceanBase 和金仓怎么选?别只看分布式,复杂查询更考验架构取舍
前端·后端·架构
Bug修理工Bubble1 小时前
Swift ARC:一个对象到底什么时候才会被释放?
前端
ClouGence1 小时前
GPT-6 做 UI 自动化测试:Demo 惊艳,但真的适合长期回归吗?
前端·chatgpt·测试
FungLeo1 小时前
成为全栈·Node 后端篇·部署上线:从本地起服到真正对外服务
node.js·后端部署·成为全栈
阿酷tony1 小时前
视频专栏列表的防录屏水印和跑马灯效果(也可网站调用)
java·前端·音视频
Bs_MoneyMagnet2 小时前
基于springboot+vue的宠物殡葬管理平台的设计与实现 源码+文档
java·javascript·vue.js·spring boot·后端·宠物
凌风的跨境分享2 小时前
Temu店群运维提效:定时策略自动化任务全场景实操指南
大数据·运维·前端·人工智能·架构·自动化