赞
踩
继上一篇文章之后一个简单的React项目模板已经搭建好了,这篇文章主要写一下简易脚手架以及业务模块的生成命令行,以往我们使用较多的是vue-cli、create-react-app等开源脚手架,但是这些脚手架不一定符合我们当前使用的环境(比如公司的通用脚手架),这个时候我们就需要针对使用环境搭建一个脚手架,来提升整体的开发效率。
为什么要使用脚手架?简单描述几点:
......
仓库代码地址:https://github.com/huhaiqing106/MyProject/tree/master/DemoCli
这个脚手架写的比较简单,主要实现了两个功能:
work init <project-name> <git or svn>
根据可选仓库拉取远程模板,初始化一个项目work create <business-pageName>
根据GIT仓库拉取业务模块模板,生成业务木块项目结构(这个模板没有实现功能,可以从这些方面去入手,比如包含一个标砖的查询界面或者内置一些通用的方法增、删、查、改等,可以快速构建一个简单的查询界面)npm init -y
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动画
在bin
目录下创建work-cli.js
文件,文件顶部注解是告诉系统用node
去执行,添加init
命令
- #! /usr/bin/env node
-
- const program = require('commander');
-
- // 定义当前版本
- // 定义使用方法
- // 定义四个指令
- program
- .version(require('../package.json').version)
- .usage('<command> [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
执行,控制台会出现如下结果
如果每次都输入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
就可以运行了
我们可以通过npm list -g --depth 0
查看全局的依赖,然后通过npm unlink
卸载挂载到全局的命令,卸载的命令名就是当前工程下package.json
中的name
当执行work init
时,node
会自动从bin
目录下查找work-cli-xxx.js
的文件
work init <project-name> <git or svn>
work-cli-init.js
代码如下,处理argv
的参数以及分发到对应的仓库文件拉取模板,然后删除从仓库拉取下来之后目录中的.git
/.svn
文件,让目录与拉取仓库解绑,目录文件不展示仓库状态图标
- #!/usr/bin/env node
-
- const 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('<project-name> <git or svn>');
- program.parse(process.argv);
-
- // 当没有输入参数的时候提示
- if (program.args.length < 1) return program.help();
-
- const projectName = program.args[0];
- // 校验下项目名称
- if (!projectName) {
- console.log(chalk.red('n Project should not be empty! n'));
- return;
- }
-
- const warehouseType = program.args[1];
- // 校验仓库类型
- if (!warehouseType) {
- console.log(chalk.red('n Warehouse should not be empty! n'));
- return;
- }
-
- console.log(chalk.white('n Start generating... n'));
- // 加载图标
- const spinner = ora('Downloading...');
- spinner.start();
-
- const callBack = (err, fileName) => {
- spinner.succeed();
- if (err) {
- console.log(chalk.red('n Copy project template exception'));
- console.log(`n ${err}`);
- } else {
- try {
- deleteFolder('./' + projectName, fileName);
- } catch (error) {
- console.log(chalk.yellow('n Delete ' + fileName + ' folder exception, but does not affect operation'));
- }
- console.log(chalk.green('n Generation completed!'));
- console.log('n To get started');
- console.log(`n cd ${projectName} n`);
- }
- };
-
- if (warehouseType === 'svn') {
- initSvn(projectName).then((err) => {
- callBack(err, '.svn');
- });
- } else {
- const repository = 'direct:https://github.com/huhaiqing106/react-temlpate.git';
- initGit(repository, projectName).then((err) => {
- callBack(err, '.git');
- });
- }
Git仓库拉取的时候repository
需要特别注意下地址一定要带上direct:
,GIT地址从这里copy,然后加上direct:
这个文件很简单,就是从GIT拉取模板
- const download = require('download-git-repo');
-
- module.exports = (repository, projectName) => {
- return new Promise((resolve, reject) => {
- download(repository, projectName, { clone: true }, function (err) {
- resolve(err);
- });
- });
- };
- const svnUltiMate = require('node-svn-ultimate');
-
- module.exports = (projectName) => {
- const svnUrl = 'xxxx';
-
- return new Promise((resolve, reject) => {
- svnUltiMate.commands.checkout(svnUrl, projectName, { username: 'xxx', password: 'xxx' }, function (err) {
- resolve(err);
- });
- });
- };
这个文件是从SVN仓库拉取模板,这里需要注意几点,因为node
是通过命令行去拉取的模板,所以我们的环境需要支持svn
命令,参考如下:
step 1
安装SVN
命令行工具,附下载地址
下载Apache Subversion command line tools,这是一个可以在cmd
下使用的命令行工具,解压后把里面bin
目录这个路径添加到环境变量的path
,这样在cmd
下就可以使用了,和Linux
下使用svn
的习惯一样了。
step 2
配置环境变量
安装目录Apache-Subversionbin
这个文件主要是递归删除从仓库拉取下来的模板中的隐藏文件.svn
/.git
- const fs = require('fs');
-
- /**
- * 寻找.svn文件,删除svn关联
- *
- * @param {*} pathStr
- */
- function deleteFolder(pathStr, fileName) {
- let files = [];
- if (fs.existsSync(pathStr)) {
- files = fs.readdirSync(pathStr, 'utf8');
- files.forEach(function (file, index) {
- let curPath = pathStr + '/' + file;
- // 匹配特定SVN文件夹,然后移除
- if (new RegExp(`^${fileName}$`).test(file)) {
- deleteFile(curPath);
- }
- });
- }
- }
-
- /**
- * 删除svn文件夹与文件
- *
- * @param {*} pathStr
- */
- function deleteFile(pathStr) {
- let files = [];
- if (fs.existsSync(pathStr)) {
- files = fs.readdirSync(pathStr, 'utf8');
- files.forEach(function (file, index) {
- let curPath = pathStr + '/' + file;
- if (fs.statSync(curPath).isDirectory()) {
- deleteFile(curPath);
- } else {
- fs.unlinkSync(curPath);
- }
- });
- fs.rmdirSync(pathStr);
- }
- }
-
- module.exports = deleteFolder;
create命令也一样,只是拉取的模板不同而已,所以直接上代码
- const program = require('commander');
- const chalk = require('chalk');
- const initGit = require('./work-cli-git');
- const ora = require('ora');
- const deleteFolder = require('./common/deleteFile');
-
- program.usage('<business-pageName>');
- program.parse(program.args);
-
- if (program.args.length < 1) {
- return program.help();
- }
-
- const pageName = program.args[0];
-
- if (!pageName) {
- console.log(chalk.red('n PageName should not be empty n'));
- return;
- }
-
- console.log(chalk.white('n Start generating... n'));
- // 加载图标
- const spinner = ora('Downloading...');
- spinner.start();
-
- const repository = 'direct:https://github.com/huhaiqing106/business-page-template.git';
- initGit(repository, pageName).then((err) => {
- spinner.succeed();
- if (err) {
- console.log(chalk.red('n Copy business page template exception'));
- console.log(`n ${err}`);
- } else {
- try {
- deleteFolder('./' + pageName, '.git');
- } catch (error) {
- console.log(chalk.yellow('n Delete ' + fileName + ' folder exception, but does not affect operation'));
- }
- console.log(chalk.green('n Generation completed!'));
- }
- });
至此一个简易的脚手架已经搭建好了,本地我们可以通过npm link
挂载到全局测试,测试通过之后,我们在发布到npm私服,然后通过npm install xxx -g
将依赖安装到全局之后,就可以开心的玩耍了
SVN安装教程:https://www.jianshu.com/p/725e49003e44
SVN命令行工具: http://www.visualsvn.com/downloads/
参考资料:https://juejin.cn/post/6844903807919325192#heading-10
第一次记录写文章,文笔有限,多多包涵,ヾ(´ー`)ノ゛谢谢♪
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。