一个简单的脚手架的搭建方法

因为各种原因,总之就是需要快速搭建一个简单的脚手架,好的,开码。ヾ(◍°∇°◍)ノ゙

目录搭建

不管三七二十一,首先就要创建一个文件夹,命名为 gis-cli。

在该目录下执行 npm init 命令,生成一个生成 package.json 文件,在 package.json 里面写入以下依赖并执行 npm install 安装,如下:

  "dependencies": {
    "chalk": "^2.4.2",
    "commander": "^3.0.1",
    "download-git-repo": "^2.0.0",
    "inquirer": "^7.0.0",
    "ora": "^3.4.0"
  }

整个脚手架的目录结构是

|--gis-cli
    |-- bin
    	|-- gis
    	|-- gis-add
    	|-- gis-delete
    	|-- gis-init
    	|-- gis-list
    |-- .gitignore     
    |-- .npmignore  
    |-- package.json
    |-- package-lock.json
    |-- README.md
    |-- template.json

bin文件下

  • gis:入口文件,主要用于定义指令

  • gis-add:定义指令gis add的相关文件

  • gis-delete:定义指令gis add的相关文件

  • gis-init:定义指令gis add的相关文件

  • gis-list:定义指令gis add的相关文件

.gitignore: git的忽略文件 .npmignore:npm的忽略文件 package.json: 相关依赖以及npm配置 README.md: 说明文档 template.json: 存放模板对应地址

文件内容

package.json文件

{
  "name": "gismap4-cli",
  "version": "1.0.0",
  "description": "arcgis相关npm包的脚手架工具",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "ssh://git@git.ascs.tech/~xudaini/gismap4-cli.git"
  },
  "keywords": [
    "arcgis"
  ],
  "author": "xudaini <xudaini@ascs.tech>",
  "license": "MIT",
  "bin": {
    "gis": "bin/gis",
    "gis-add": "bin/gis-add",
    "gis-delete": "bin/gis-delete",
    "gis-list": "bin/gis-list",
    "gis-init": "bin/gis-init"
  },
  "dependencies": {
    "chalk": "^2.4.2",
    "commander": "^3.0.1",
    "download-git-repo": "^2.0.0",
    "inquirer": "^7.0.0",
    "ora": "^3.4.0"
  }
}
  • bin 用来指定每个命令所对应的可执行文件的位置

gis文件

#!/usr/bin/env node
const program = require('commander');

// 定义当前版本
// 定义使用方法
// 定义四个指令
program
	.version(require('../package').version)
	.usage('<command> [options]')
	.command('add', 'add a new template')
	.command('delete', 'delete a template')
	.command('list', 'list all the templates')
	.command('init', 'generate a new project from a template');

// 解析命令行参数
program.parse(process.argv);

gis-add文件

#!/usr/bin/env node

const inquirer = require('inquirer');
const chalk = require('chalk');
const fs = require('fs');
const tplObj = require(`${__dirname}/../template`);

let question = [
	{
		name: "name",
		type: 'input',
		message: "请输入模板名称",
		validate(val) {
			if (val === '') {
				return 'Name is required!'
			} else if (tplObj[val]) {
				return 'Template has already existed!'
			} else {
				return true
			}
		}
	},
	{
		name: "url",
		type: 'input',
		message: "请输入模板地址",
		validate(val) {
			if (val === '') return 'The url is required!';
			return true
		}
	}
];

inquirer
	.prompt(question).then(answers => {
	
	let {name, url} = answers;
	// 过滤 unicode 字符
	tplObj[name] = url.replace(/[\u0000-\u0019]/g, '');
	
	fs.writeFile(`${__dirname}/../template.json`, JSON.stringify(tplObj), 'utf-8', err => {
		if (err) console.log(err);
		console.log('\n');
		console.log(chalk.green('Added successfully!\n'));
		console.log(chalk.grey('The latest template list is: \n'));
		console.log(tplObj);
		console.log('\n')
	})
});

gis-init文件

#!/usr/bin/env node

const program = require('commander');
const chalk = require('chalk');
const ora = require('ora');
const download = require('download-git-repo');
const tplObj = require(`${__dirname}/../template`);

program
	.usage('<template-name> [project-name]');
program.parse(process.argv);
// 当没有输入参数的时候给个提示
if (program.args.length < 1) return program.help();

// 第一个参数是 模板名,第二个参数是 project-name
let templateName = program.args[0];
let projectName = program.args[1];
// 校验参数
if (!tplObj[templateName]) {
	console.log(chalk.red('\n Template does not exit! \n '));
	return
}
if (!projectName) {
	console.log(chalk.red('\n Project should not be empty! \n '));
	return
}

url = `direct:${tplObj[templateName]}`;

console.log(chalk.white('\n Start generating... \n'));

const spinner = ora("Downloading...");
spinner.start();
// 执行下载方法并传入参数
download(
	url,
	projectName,
	{clone: true},
	err => {
		if (err) {
			spinner.fail();
			console.log(chalk.red(`Download template failed. ${err}`));
			return
		}
		
		spinner.succeed();
		console.log(chalk.green('\n Download template successful!'));
		console.log('\n To get started');
		console.log(`\n cd ${projectName} \n`)
	}
);

template.json文件

{}

其他文件略。

附注

download-git-repo的使用方法

Shorthand

使用来自Github的http形式下载。

download('flipxfx/download-git-repo-fixture', 'test/tmp', function (err) {  console.log(err ? 'Error' : 'Success')})

使用Bitbucket中的git clone形式下载develop分支。

download('bitbucket:flipxfx/download-git-repo-fixture#my-branch', 'test/tmp', { clone: true }, function (err) {  console.log(err ? 'Error' : 'Success')})

使用GitLab的http下载以及自定义源和令牌

download('gitlab:mygitlab.com:flipxfx/download-git-repo-fixture#my-branch', 'test/tmp', { headers: { 'PRIVATE-TOKEN': '1234' } } function (err) {  console.log(err ? 'Error' : 'Success')})

使用GitLab中的git clone形式下载my-branch分支,自定义源和令牌

download('https://mygitlab.com:flipxfx/download-git-repo-fixture#my-branch', 'test/tmp', { clone: true }, function (err) {  console.log(err ? 'Error' : 'Success')})

Direct

直接使用网址的http下载。

download('direct:https://gitlab.com/flipxfx/download-git-repo-fixture/repository/archive.zip', 'test/tmp', function (err) {  console.log(err ? 'Error' : 'Success')})

直接使用url的git clone下载master分支

download('direct:https://gitlab.com/flipxfx/download-git-repo-fixture.git', 'test/tmp', { clone: true }, function (err) {  console.log(err ? 'Error' : 'Success')})

直接使用url网址的git clone下载my-branch的分支

download('direct:https://gitlab.com/flipxfx/download-git-repo-fixture.git#my-branch', 'test/tmp', { clone: true }, function (err) {  console.log(err ? 'Error' : 'Success')})

上传npm

最后一步就是上传npm,然后就可以使用npm install 下载了哈哈哈哈

顺手贴一个仓库地址

参考资料

仿 vue-cli 搭建属于自己的脚手架

基于node.js的脚手架工具开发经历

搭建自己的脚手架—“优雅”生成前端工程