0
点赞
收藏
分享

微信扫一扫

如何自己搭一个脚手架

如何自己搭一个脚手架

javascriptnode.jsgithub

前言

做前端也有三四年了,自己带了个五人前端小团队,第一次写脚手架,也是第一次写分享文章。文笔太差,勿喷、勿喷、勿喷    
每次人肉搬运代码的时候,就想自己能不能给团队做一个跟vue-cli一样的脚手架?想了很久,苦于各种原因一直没有实施。
正好最近不忙,此时不搞,更待何时!开搞,网上查文档,gitHub扒vue-cli的源码,坑哧吭哧的捣鼓了两天……成了。拿出来分享一下吧。

准备工作

一、gitHub新建组织和仓库

这个不难,一张图概括,按照提示步骤填写信息就好了。如下图,我创建了一个叫​​template-organization​​的组织。

如何自己搭一个脚手架_git

组织创建完之后,就可以在​​template-organization​​​这个组织下创建新的仓库​​demo-template​

如何自己搭一个脚手架_git_02

如何自己搭一个脚手架_git_03

重点来了,​​https://api.github.com/users/...​​,获取template-organization这个组织下的所有仓库信息。

二、npm账号

** 注册账号:** 
** 登录: **
** 添加用户信息到注册表 **
npm adduser

主体内容

写代码

准备工作做齐了,开始coding……

打开终端,初始化项目

$ `mkdir edu-test-cli`
$ `cd edu-test-cli/`
$ `npm init`
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (edu-test-cli)
version: (1.0.0)
description: 这个是一个简单的脚手架
entry point: (index.js)
test command:
git repository:
keywords: cli edu zhx
author: 张鑫
license: (ISC) MIT
About to write to /Users/zhangxin/study/edu-test-cli/package.json:

{
"name": "edu-test-cli",
"version": "1.0.0",
"description": "这个是一个简单的脚手架",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"cli",
"edu",
"zhx"
],
"author": "张鑫",
"license": "MIT"
}


Is this ok? (yes) yes

项目的​​package.json​​结构就基本出来了。

加入依赖的包

npm i chalk commander download-git-repo inquirer ora request --save

修改package.json中配置,如下

{
"name": "edu-test-cli",
"version": "1.0.0",
"description": "这个是一个简单的脚手架",
"preferGlobal": true,
"bin": {
"edu": "bin/edu"
},
"dependencies": {
"chalk": "^1.1.3",
"commander": "^2.9.0",
"download-git-repo": "^1.1.0",
"inquirer": "^6.2.0",
"ora": "^3.0.0",
"request": "^2.88.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"cli",
"edu",
"zhx"
],
"author": "张鑫",
"license": "MIT"
}

项目结构,如下

>edu-test-cli
|--bin
|--edu
|--lib
|--list.js
|--init.js
|--package.json
|--README.md

在bin目录下新建 ​​edu​​ (没有后缀),代码如下

#!/usr/bin/env node
process.env.NODE_PATH = __dirname + '/../node_modules/'

const program = require('commander')

program
.version(require('../package.json').version)
.usage('<command> [options]')
program
.command('list')
.description('查看所有的模版')
.alias('l')
.action(() => {
require('../lib/list')()
})
program
.command('init')
.description('生成一个新项目')
.alias('i')
.action(() => {
require('../lib/init')()
})
program
.parse(process.argv)

if(!program.args.length){
program.help()
}

lib目录下 ​​init.js​​,代码如下

const ora = require('ora')
const inquirer = require('inquirer')
const chalk = require('chalk')
const request = require('request')
const download = require('download-git-repo')

module.exports = () => {
request({
url: 'https://api.github.com/users/template-organization/repos',
headers: {
'User-Agent': 'edu-test-cli'
}
}, (err, res, body) =>{
if (err) {
console.log(chalk.red('查询模版列表失败'))
console.log(chalk.red(err))
process.exit();
}

const requestBody = JSON.parse(body)
if (Array.isArray(requestBody)) {
let tplNames = [];
requestBody.forEach(repo => {
tplNames.push(repo.name);
})

let promptList = [
{
type: 'list',
message: '请选择模版',
name: 'tplName',
choices: tplNames
},
{
type: 'input',
message: '请输入项目名字',
name: 'projectName',
validate (val) {
if (val !== '') {
return true
}
return '项目名称不能为空'
}
}
]
inquirer.prompt(promptList).then(answers => {

let ind = requestBody.find(function (ele) {
return answers.tplName == ele.name;
});
let gitUrl = `${ind.full_name}#${ind.default_branch}`,
defaultUrl = './',
projectUrl = `${defaultUrl}/${answers.projectName}`,
spinner = ora('\n 开始生成项目,请等待...');
spinner.start();
download(gitUrl, projectUrl, (error)=>{
spinner.stop();
if (error) {
console.log('模版下载失败……')
console.log(error)
process.exit()
}
console.log(chalk.green(`\n √ ${answers.projectName} 项目生成完毕!`))
console.log(`\n cd ${answers.projectName} && npm install \n`)
})
})
} else {
console.error(requestBody.message)
}
})
}

lib目录下的 ​​list.js​​,代码如下:

const request = require('request');
const chalk = require('chalk')
const ora = require('ora')
module.exports = () => {
let spinner = ora('\n ' + chalk.yellow('正在查询模版列表,请等待...'));
spinner.start();
request({
url: 'https://api.github.com/users/template-organization/repos',
headers: {
'User-Agent': 'edu-test-cli'
}
}, (err, res, body) => {
spinner.stop();
if (err) {
console.log(chalk.red('查询模版列表失败'))
console.log(chalk.red(err))
process.exit();
}
const requestBody = JSON.parse(body)
if (Array.isArray(requestBody)) {
console.log()
console.log(chalk.green('可用的模版列表:'))
console.log()
requestBody.forEach(repo => {
console.log(
' ' + chalk.yellow('★') +
' ' + chalk.blue(repo.name) +
' - ' + repo.description)
})
} else {
console.error(requestBody.message)
}
})
}

到这里这个简单的脚手架就开发完了。代码都在这里,是不是很简单呢?

开发、测试、发布

开发时,可使用以下命令查看效果

node bin/edu list   查看所有可用的模版
node bin/edu init 把模版下载下来,作为初始项目进行开发

测试时,如何使用全局的 ​​edu list/init​​ 的命令呢?

npm link    ///只能自己本地使用。

开发、测试完成,发布

npm publish  ///将包发布到npm上,所有人都可以安装使用。

例子:
edu-test-cli> $ npm publish
+ edu-test-cli@1.1.0

使用方法

安装

npm install -g edu-test-cli

查看模版列表

$ edu list

可用的模版列表:

★ demo-template - 这是一个关于移动端适配方案的示例项目。

创建项目

$ edu init
? 请选择模版 (Use arrow keys)
❯ demo-template

? 请输入项目名字

结尾

终于写完了。写文章比写代码还累。。。。。。



举报

相关推荐

0 条评论