zoukankan      html  css  js  c++  java
  • 如何自己搭一个脚手架

    如何自己搭一个脚手架

    前言

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

    准备工作

    一、gitHub新建组织和仓库

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

    clipboard.png

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

    clipboard.png

    clipboard.png

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

    二、npm账号

    ** 注册账号:** 
        [https://www.npmjs.com/][2]
    ** 登录: ** 
        npm login
    ** 添加用户信息到注册表 ** 
        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('
     开始生成项目,请等待...');
              spinner.start();
            download(gitUrl, projectUrl, (error)=>{
              spinner.stop();
              if (error) {
                console.log('模版下载失败……')
                console.log(error)
                process.exit()
              }
              console.log(chalk.green(`
     √ ${answers.projectName} 项目生成完毕!`))
              console.log(`
     cd ${answers.projectName} && npm install 
    `)
            })
          })
        } 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('
     ' + 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 
      
    ? 请输入项目名字
    

    结尾

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

  • 相关阅读:
    Spring MVC常用注解
    SQL预处理
    浅析用链表实现的队列
    logrotate自动切割某一服务模板
    3种安装nginx的方法以及相关的配置文件
    一键部署NFS服务端脚本
    rsync排错
    NFS排错
    nfs客户端 一键切换 nfs高可用主机脚本
    实时监控nfs服务端是否宕机
  • 原文地址:https://www.cnblogs.com/onesea/p/13048306.html
Copyright © 2011-2022 走看看