背景脚手架是一种通用的开发工具。在编写原生web项目之前,总是需要反复搭建开发环境,编写几乎相同的配置文件。为了避免每次重复劳动,统一开发环境和规范,想到自己写一个脚手架,顺便记录一下。目前我个人习惯是基于目前主流的webpack打包工具开发项目,所以本脚手架是基于webpack5开发的。概述在本文中,我们首先将最基本的功能实现为一个脚手架:输入命令创建统一模板项目开发依赖于开发一个脚手架,你至少需要以下npm包:commander:命令行处理工具inquirer:命令行交互工具download-git-repo:git仓库下载工具ora:终端加载美化工具chalk:命令行输入/输出美化工具初始化项目mkdirweb-clidweb-clinpminit-y定义package.json配置文件中的bin字段node.js内置了对命令行的支持操作的backingbin字段可以定义命令名称和关联的可执行文件。项目将使用ES6模块化开发,需要转换成common.js模块化,最终执行命令的node.js可以识别。在脚本中定义Babel编译的命令“bin”:{"web":"./bin/index.js"}在根目录下创建一个src/index.js文件作为入口,在行首#!/usr/bin/envnode指定当前脚本由node.js解析Babel配置项目将使用ES6模块进行开发,需要配置Babel将其转换为common.js模块,可以被执行最终命令的node.js识别,并安装相关依赖:npminstall--save-dev@babel/core@babel/cli@babel/preset-envpackage.json配置文件中的script字段定义Babel编译的命令"scripts":{"build":"babelsrc-ddist"}添加Babel配置文件babel.config.json{"presets":["@babel/preset-env"]}测试effect除了将项目打包并全局安装,我们还可以在项目根目录下执行npmlink命令,将指定的执行文件链接到global环境。我们在入口代码中写入一个输出helloworld#!/usr/bin/envnodeconsole.log('heloworld!')。执行npm链接后,我们打开命令行终端,输入:web可以看到输出helloworldtemplateProject我们需要创建一个完成通用配置的模板工程,并上传到GitHub的公共仓库。这一步就不多做演示了。我创建了一个基于webpack5的项目模板,完成了htmlWebpackPlugin、css资源处理、JavaScript资源处理和基础优化等基本配置:https://github.com/LeoJ340/we...接下来,我们需要拉取仓库代码和动态配置一些个人信息。需要实现的逻辑是:在命令行输入创建项目的命令和项目名称,输入项目或作者的基本信息,去GitHub拉取模板项目到自定义项目的目录下命名,根据读取的项目信息修改package.json配置安装相关依赖:npminstallcommanderdownload-git-repoinquirer@6.5.0commandercommander是一个第三方库,用于注册命令和获取命令行参数。commander注册命令的基本用法如下:import{program}from'commander';program.command('command[parameter]','commanddescription',opts).action(callbackfunction)//解析参数用户在执行过程中输入//process.argv是nodejsprogram.parse(process.argv)提供的一个属性;down??load-git-repodownload-git-repo是一个用于下载GitHub和Gitlab公共仓库的库。基本用法如下:importdownloadfrom'download-git-repo';down??load(repository,destination,options,callback)repository:远程仓库的地址destination:下载到本地的路径options:配置参数(callback:callbackfunctioninquiryrinquirer是一个提供命令行交互操作的库(新版inquirer只支持ESM,即使用babel编译也会报错,所以这里需要使用旧版本),其用法也很简单(取自官网):importinquirerfrom'inquirer';inquirer.prompt([/*Passyourquestionsinhere*/])。then((answers)=>{//将用户反馈用于...无论什么!!}).catch((error)=>{if(error.isTtyError){//在当前环境中无法呈现提示}else{//其他地方出错了}});接下来我们修改入口代码:#!/usr/bin/envnodeimport{program}from'commander';importinquirerfrom'inquirer';importdownloadfrom'download-git-repo';program.version('1.0.0')//注册创建命令,name作为参数指的是项目名program.command('create
