热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

gitlog获取构建时间_前端项目搭建部署全流程(四):脚手架与业务模块构建...

1.前言继上一篇文章之后一个简单的React项目模板已经搭建好了,这篇文章主要写一下简易脚手架以及业务模块的生成命令行,以往我们使用较多的是vue-cl
e0add435b62ab4daa2d6da7f50707199.png

1.前言

继上一篇文章之后一个简单的React项目模板已经搭建好了,这篇文章主要写一下简易脚手架以及业务模块的生成命令行,以往我们使用较多的是vue-cli、create-react-app等开源脚手架,但是这些脚手架不一定符合我们当前使用的环境(比如公司的通用脚手架),这个时候我们就需要针对使用环境搭建一个脚手架,来提升整体的开发效率。

为什么要使用脚手架?简单描述几点:
  1. 减少重复的工作,不需要在内部通过ctrl+c、ctrl+v的方式复制项目结构
  2. 可以保持整个工程的项目结构以及编码规范保持一致等

......

仓库代码地址:https://github.com/huhaiqing106/MyProject/tree/master/DemoCli

2.支持的功能

这个脚手架写的比较简单,主要实现了两个功能:

  1. work init 根据可选仓库拉取远程模板,初始化一个项目
  2. work create 根据GIT仓库拉取业务模块模板,生成业务木块项目结构(这个模板没有实现功能,可以从这些方面去入手,比如包含一个标砖的查询界面或者内置一些通用的方法增、删、查、改等,可以快速构建一个简单的查询界面)

3.初始化项目

npm init -y

3.1.安装依赖

yarn add chalk commander download-git-repo inquirer node-svn-ultimate ora --dev

chalk修改控制台输出内容样式

commander命令行工具

download-git-repo从GIT拉取远程模板

inquirer交互式命令行工具

node-svn-ultimate从SVN拉取远程模板

ora显示loading动画

3.2.创建bin目录

bin目录下创建work-cli.js文件,文件顶部注解是告诉系统用node去执行,添加init命令

#! /usr/bin/env nodeconst program = require('commander');// 定义当前版本
// 定义使用方法
// 定义四个指令
program.version(require('../package.json').version).usage(' [options]')// 后期扩展支持根据配置的地址初始化模板// .command("init-config", "generate a new project from a config template").command('init', 'generate a new project from git').command('create', 'create a new business page from git');
// 解析命令行参数
program.parse(process.argv);

创建完改文件我们通过node ./bin/work-cli 执行,控制台会出现如下结果

6c598a5aae88d8d174a3f117d2d9ea73.png

如果每次都输入node ./bin/work-cli 就比较麻烦了,我们重新在package.json中增加启动命令

{"name": "work-cli","version": "0.0.1","description": "work cli","main": "index.js","bin": {"work": "bin/work-cli.js"},...
}

然后通过npm link挂载到全局,这样就只需要输入work就可以运行了

8ba3a71d52bdf3218468189c6f77a586.png

我们可以通过npm list -g --depth 0查看全局的依赖,然后通过npm unlink卸载挂载到全局的命令,卸载的命令名就是当前工程下package.json中的name

c2432cc69fa0300f8ea1dc14607b2456.png

4.编写command命令

4.1.init命令

当执行work init时,node会自动从bin目录下查找work-cli-xxx.js的文件

work init

work-cli-init.js代码如下,处理argv的参数以及分发到对应的仓库文件拉取模板,然后删除从仓库拉取下来之后目录中的.git/.svn文件,让目录与拉取仓库解绑,目录文件不展示仓库状态图标

#!/usr/bin/env nodeconst program = require('commander');
const chalk = require('chalk');
const ora = require('ora');
const initSvn = require('./work-cli-svn');
const initGit = require('./work-cli-git');
const deleteFolder = require('./common/deleteFile');program.usage(' ');
program.parse(process.argv);// 当没有输入参数的时候提示
if (program.args.length <1) return program.help();const projectName &#61; program.args[0];
// 校验下项目名称
if (!projectName) {console.log(chalk.red(&#39;n Project should not be empty! n&#39;));return;
}const warehouseType &#61; program.args[1];
// 校验仓库类型
if (!warehouseType) {console.log(chalk.red(&#39;n Warehouse should not be empty! n&#39;));return;
}console.log(chalk.white(&#39;n Start generating... n&#39;));
// 加载图标
const spinner &#61; ora(&#39;Downloading...&#39;);
spinner.start();const callBack &#61; (err, fileName) &#61;> {spinner.succeed();if (err) {console.log(chalk.red(&#39;n Copy project template exception&#39;));console.log(&#96;n ${err}&#96;);} else {try {deleteFolder(&#39;./&#39; &#43; projectName, fileName);} catch (error) {console.log(chalk.yellow(&#39;n Delete &#39; &#43; fileName &#43; &#39; folder exception, but does not affect operation&#39;));}console.log(chalk.green(&#39;n Generation completed!&#39;));console.log(&#39;n To get started&#39;);console.log(&#96;n cd ${projectName} n&#96;);}
};if (warehouseType &#61;&#61;&#61; &#39;svn&#39;) {initSvn(projectName).then((err) &#61;> {callBack(err, &#39;.svn&#39;);});
} else {const repository &#61; &#39;direct:https://github.com/huhaiqing106/react-temlpate.git&#39;;initGit(repository, projectName).then((err) &#61;> {callBack(err, &#39;.git&#39;);});
}

Git仓库拉取的时候repository需要特别注意下地址一定要带上direct:&#xff0c;GIT地址从这里copy&#xff0c;然后加上direct:

3aa8adf16096151f9bb92b11ae522d4d.png

4.1.1.work-cli-git文件

这个文件很简单&#xff0c;就是从GIT拉取模板

const download &#61; require(&#39;download-git-repo&#39;);module.exports &#61; (repository, projectName) &#61;> {return new Promise((resolve, reject) &#61;> {download(repository, projectName, { clone: true }, function (err) {resolve(err);});});
};

4.1.2.work-cli-svn文件

const svnUltiMate &#61; require(&#39;node-svn-ultimate&#39;);module.exports &#61; (projectName) &#61;> {const svnUrl &#61; &#39;xxxx&#39;;return new Promise((resolve, reject) &#61;> {svnUltiMate.commands.checkout(svnUrl, projectName, { username: &#39;xxx&#39;, password: &#39;xxx&#39; }, function (err) {resolve(err);});});
};

这个文件是从SVN仓库拉取模板&#xff0c;这里需要注意几点&#xff0c;因为node是通过命令行去拉取的模板&#xff0c;所以我们的环境需要支持svn命令&#xff0c;参考如下&#xff1a;

step 1

安装SVN命令行工具&#xff0c;附下载地址

下载Apache Subversion command line tools&#xff0c;这是一个可以在cmd下使用的命令行工具&#xff0c;解压后把里面bin目录这个路径添加到环境变量的path&#xff0c;这样在cmd下就可以使用了&#xff0c;和Linux下使用svn的习惯一样了。

step 2

配置环境变量

安装目录Apache-Subversionbin

4.1.3.deleteFile文件

这个文件主要是递归删除从仓库拉取下来的模板中的隐藏文件.svn/.git

const fs &#61; require(&#39;fs&#39;);/*** 寻找.svn文件&#xff0c;删除svn关联** &#64;param {*} pathStr*/
function deleteFolder(pathStr, fileName) {let files &#61; [];if (fs.existsSync(pathStr)) {files &#61; fs.readdirSync(pathStr, &#39;utf8&#39;);files.forEach(function (file, index) {let curPath &#61; pathStr &#43; &#39;/&#39; &#43; file;// 匹配特定SVN文件夹&#xff0c;然后移除if (new RegExp(&#96;^${fileName}$&#96;).test(file)) {deleteFile(curPath);}});}
}/*** 删除svn文件夹与文件** &#64;param {*} pathStr*/
function deleteFile(pathStr) {let files &#61; [];if (fs.existsSync(pathStr)) {files &#61; fs.readdirSync(pathStr, &#39;utf8&#39;);files.forEach(function (file, index) {let curPath &#61; pathStr &#43; &#39;/&#39; &#43; file;if (fs.statSync(curPath).isDirectory()) {deleteFile(curPath);} else {fs.unlinkSync(curPath);}});fs.rmdirSync(pathStr);}
}module.exports &#61; deleteFolder;

4.2.create命令

create命令也一样&#xff0c;只是拉取的模板不同而已&#xff0c;所以直接上代码

const program &#61; require(&#39;commander&#39;);
const chalk &#61; require(&#39;chalk&#39;);
const initGit &#61; require(&#39;./work-cli-git&#39;);
const ora &#61; require(&#39;ora&#39;);
const deleteFolder &#61; require(&#39;./common/deleteFile&#39;);program.usage(&#39;&#39;);
program.parse(program.args);if (program.args.length <1) {return program.help();
}const pageName &#61; program.args[0];if (!pageName) {console.log(chalk.red(&#39;n PageName should not be empty n&#39;));return;
}console.log(chalk.white(&#39;n Start generating... n&#39;));
// 加载图标
const spinner &#61; ora(&#39;Downloading...&#39;);
spinner.start();const repository &#61; &#39;direct:https://github.com/huhaiqing106/business-page-template.git&#39;;
initGit(repository, pageName).then((err) &#61;> {spinner.succeed();if (err) {console.log(chalk.red(&#39;n Copy business page template exception&#39;));console.log(&#96;n ${err}&#96;);} else {try {deleteFolder(&#39;./&#39; &#43; pageName, &#39;.git&#39;);} catch (error) {console.log(chalk.yellow(&#39;n Delete &#39; &#43; fileName &#43; &#39; folder exception, but does not affect operation&#39;));}console.log(chalk.green(&#39;n Generation completed!&#39;));}
});

5.发布npm

至此一个简易的脚手架已经搭建好了&#xff0c;本地我们可以通过npm link挂载到全局测试&#xff0c;测试通过之后&#xff0c;我们在发布到npm私服&#xff0c;然后通过npm install xxx -g将依赖安装到全局之后&#xff0c;就可以开心的玩耍了

6.参考文献

SVN安装教程&#xff1a;https://www.jianshu.com/p/725e49003e44

SVN命令行工具&#xff1a; http://www.visualsvn.com/downloads/

参考资料&#xff1a;https://juejin.cn/post/6844903807919325192#heading-10

第一次记录写文章&#xff0c;文笔有限&#xff0c;多多包涵&#xff0c;ヾ(´ー&#96;)&#xff89;゛谢谢♪



推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 【Windows】实现微信双开或多开的方法及步骤详解
    本文介绍了在Windows系统下实现微信双开或多开的方法,通过安装微信电脑版、复制微信程序启动路径、修改文本文件为bat文件等步骤,实现同时登录两个或多个微信的效果。相比于使用虚拟机的方法,本方法更简单易行,适用于任何电脑,并且不会消耗过多系统资源。详细步骤和原理解释请参考本文内容。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • (三)多表代码生成的实现方法
    本文介绍了一种实现多表代码生成的方法,使用了java代码和org.jeecg框架中的相关类和接口。通过设置主表配置,可以生成父子表的数据模型。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
author-avatar
Panzerkampfwagen-VI_238
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有