
在讲解脚手架之前,我们先来看看目录结构吧:
=================
|__ bin
|__ index.js
|__ command
|__ add.js
|__ delete.js
|__ init.js
|__ list.js
|__ node_modules
|__ package.json
|__ templates.json
首先,新建pakage.json文件,写入依赖并且执行npm install
{
  "dependencies": {//必须依赖
    "chalk": "^1.1.3",
    "co": "^4.6.0",
    "co-prompt": "^1.0.0",
    "commander": "^2.9.0"
  },
  "name": "templates_wct",//模板名称,用于npm install name
  "version": "1.0.1",//发布时填写的版本号
  "description": "a tool service for react-ssr",//描述
  "main": "index.js",//入口文件名称
  "bin": {
    "snowcat": "bin/index.js"//执行名称,配置后只需:snowcat init 便可初始化。 
  },
  "author": "wct",
  "license": "ISC",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/Windseek/react-ssr-cli.git"
  },
  "keywords": [
    "react",
    "react-ssr",
    "wind-ssr",
    "react-ssr-cli"
  ],
  "bugs": {
    "url": "https://github.com/Windseek/react-ssr-cli/issues"
  },
  "homepage": "https://github.com/Windseek/react-ssr-cli#readme"
}
入口文件
在根目录下建立\bin文件夹,在里面建立一个index.js文件。这个bin\index.js文件是整个脚手架的入口文件,所以我们首先对它进行编写。
首先是一些初始化的代码:
#!/usr/bin/env node
const { resolve } = require('path')
const program = require('commander')
process.env.NODE_PATH = resolve(__dirname, '../node_modules/')
const { version } = require(resolve(__dirname, '../package.json'))
// const version = require('../package');
// process.env.NODE_PATH = __dirname + '/../node_modules/';
program
  .version(version)
program
  .usage('<commands>')
program
  .command('add')
  .description('Add a new template')
  .alias('a')
  .action(() => {
    require('../commands/add')()
  })
program
  .command('list')
  .description('List all templates')
  .alias('l')
  .action(() => {
    require('../commands/list')()
  })
program
  .command('delete')
  .description('Delete a template')
  .alias('d')
  .action(() => {
    require('../commands/delete')()
  })
program
  .command('init')
  .description('Generate a new project')
  .alias('i')
  .action(() => {
    require('../commands/init')()
  })
program.parse(process.argv)
if(!program.args.length){
  program.help()
}
从前文的架构图中我们可以看到,在根目录下创建一个/commands文件,其下有四个js文件,init,list,add,delete
在根目录下新建一个模板templates.json,用于存放模板信息;
{"tpl":{
  "react":{"url":"https://github.com/Windseek/reactssr.git","branch":"master"},
    }
}
模板初始化:init
'use strict'
const exec = require('child_process').exec;//可运行复杂的命令
const co = require('co');//异步控制流程模块,和es6标准Promise类似,基于 ES6 的 generator 和 yield,属于node圈
const prompt = require('co-prompt')
const config = require('../templates')
const chalk = require('chalk');//为了使输出不再单调,添加文字背景什么的,改变字体颜色什么的
module.exports = () => {
    co(function *() {
      // 处理用户输入
      let tplName = yield prompt('Template name (you can input one like react, vue, angular): ')
      let projectName = yield prompt('Project name: ')
      let gitUrl,branch;
      console.log(config.tpl);
      if (!config.tpl[tplName]) {
        console.log(chalk.red('\n × Template does not support!'))
        process.exit()
      }
      gitUrl = config.tpl[tplName].url
      branch = config.tpl[tplName].branch
      // git命令,远程拉取项目并自定义项目名
      let cmdStr = `git clone ${gitUrl} ${projectName} && cd ${projectName} && git checkout ${branch}`
      exec(cmdStr, (error, stdout, stderr) => {
        if (error) {
          console.log(error)
          process.exit()
        }
        console.log(chalk.green('\n √ Generation completed!'))
        console.log(`\n cd ${projectName} && npm install \n`)
        process.exit()
      })
    })
}
模板新增:add——->模板信息写进templates.json
'use strict'
const co = require('co')
const prompt = require('co-prompt')
const config = require('../templates')
const chalk = require('chalk')
const fs = require('fs')
module.exports = () => {
  co(function *() {
    // 分步接收用户输入的参数
    let tplName = yield prompt('Template name: ')
    let gitUrl = yield prompt('Git https link: ')
    let branch = yield prompt('Branch: ')
    // 避免重复添加
    if (!config.tpl[tplName]) {
     let objConfig = {};
      objConfig.url = gitUrl.replace(/[\u0000-\u0019]/g, '') // 过滤unicode字符
      objConfig.branch = branch
      config.tpl[tplName] = objConfig
    } else {
      console.log(chalk.red('Template has already existed!'))
      process.exit()
    }
    // 把模板信息写入templates.json
    fs.writeFile(__dirname + '/../templates.json', JSON.stringify(config), 'utf-8', (err) => {
      if (err) console.log(err)
      console.log(chalk.green('New template added!\n'))
      console.log(chalk.grey('The last template list is: \n'))
      console.log(config)
      console.log('\n')
      process.exit()
    })
  })
}
模板删除:delete
'use strict'
const co = require('co')
const prompt = require('co-prompt')
const config = require('../templates')
const chalk = require('chalk')
const fs = require('fs')
module.exports = () => {
  co(function *() {
    // 接收用户输入的参数
    let tplName = yield prompt('Template name: ')
    // 删除对应的模板
    if (config.tpl[tplName]) {
      config.tpl[tplName] = undefined
    } else {
      console.log(chalk.red('Template does not exist!'))
      process.exit()
    }
    // 写入template.json
    fs.writeFile(__dirname + '/../templates.json', JSON.stringify(config),     'utf-8', (err) => {
      if (err) console.log(err)
      console.log(chalk.green('Template deleted!'))
      console.log(chalk.grey('The last template list is: \n'))
      console.log(config)
      console.log('\n')
      process.exit()
    })
  })
}
查看模板列表:list
'use strict'
const config = require('../templates')
module.exports = () => {
  console.log(config.tpl)
  process.exit()
}
全局使用,在根目录下:
确认设置 package.json下的bin为:
"bin": {
    "snowcat": "bin/index.js"
  },
执行:npm link
执行snowcat 测试结果:
Usage: scion <command>
  Options:
    -h, --help     output usage information
    -V, --version  output the version number
  Commands:
    add|a      Add a new template
    list|l     List all the templates
    init|i     Generate a new project
    delete|d   Delete a template
写好了需要发布一下喽:npm账号注册(https://www.npmjs.com/)
1、npm login,填写用户名,密码
2、修改package.json里version
3、npm publish
4、去https://www.npmjs.com/上看看成功没有
相关说明:
1、package.json里定义bin的位置
2、index里定义bin命令指定执行的代码
3、init里执行shell,去git上拿代码模板
安装和初始化:
1、npm install templates_wct -g
2、snowcat init
3、选择要使用的模板,react,angular和vue
注: 原址请参考CSDN:(https://blog.csdn.net/fengyinchao/article/details/52168619)
 
                         
                                

