用node搭建属于自己的脚手架

751 阅读2分钟

自定义脚手架工具解决问题

  • 1.可以自定义需要导入的文件;
  • 2.自定义框架选择;
  • 3.减少自己的一些重复性的工作。

脚手架的整体流程

  • 1.根据用户输入来生成不同的框架配置文件;
  • 2.下载指定后的模板;
  • 3.根据用户信息的不同,生成不同package.json;
  • 4.生成新的工程文件。

脚手架需要用到的依赖

  • 1.commander:参数解析工具。用它来读取用户输入的数据,并且根据用户输入的数据来进行一定的操作。
  • 2.inquirer:交互式的命令行工具。用它通过选择、读取、判断的方式读取用户的数据。
  • 3.download-git-repo:下载远程模板的工具。用它来下载在git上配置好的模板。
  • 4.ora:用户显示加载中的效果。显示一个loading的效果,提升用户交互友好度。
  • 5.chalk:将console.log打印的内容颜色进行修改。

开发步骤

一、初始化

  • 1.创建项目文件夹;

  • 2.npm init –y初始化项目;

  • 3.创建入口文件;

  • 4.并在package.json中追加’bin’的链接的入口文件地址;

  • 5.用npm link链接到全局。


    package.json

{
  "name": "wangjian-cli",
  "version": "2.0.0",
  "description": "",
  "main": "index.js",
  "bin": {
    "wangjian-cli": "./bin/app.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.21.1",
    "chalk": "^4.1.2",
    "commander": "^8.1.0",
    "download-git-repo": "^3.0.2",
    "inquirer": "^8.1.2",
    "ora": "^5.4.1"
  },
  "devDependencies": {
    "eslint": "^7.32.0"
  }
}

#! /usr/bin/env node  //告诉该脚本由node来执行

// 该文件作为cli的入口文件
require('../src/main.js');

二、使用commander处理参数

  • 1.npm install commander;
  • 2.const program=require(‘commander’)
program
      .command(action) // 配置命令的名字
      .alias(alias) // 配置命令的简写
      .description(description) //配置命令的描述
      .action(() => {
        if (action === '*') return console.log(chalk.red(description));
        const param = process.argv.slice(3);
        require(`./command/${action}`)(...param);
      });

三、在git上创建模板仓库

  • 1.可以在git上建立组织,然后只下载这个组织内的模板;
  • 2.在cli create的时候,遍历这个组织的仓库以及tags,用inquirer 进行命令行问答,达到一种动态配置的效果。
// 获取项目列表
const getRepoList = async () => {
  const { data } = await axios.get('https://api.github.com/orgs/wangjian-cli/repos');
  const resultArr = data.map(item => item.name);
  return resultArr;
};

// 获取版本号
const getTagList = async repo => {
  const { data } = await axios.get(`https://api.github.com/repos/wangjian-cli/${repo}/tags`);
  const resultArr = data.map(item => item.name);
  return resultArr;
};

四、使用download-git-repo从git上下载模板

  • 1.npm install download-git-repo ;
  • 2.const downloadGitRepo=require(‘download-git-repo’)
// download-git-repo下载模板
const download = async (repo, tag, projectName) => {
  let api = `wangjian-cli/${repo}/`;
  if (tag) api += `#${tag}`;
  // process.cwd()代表下载到当前打开的node的这个文件夹
  const dest = path.resolve(process.cwd(), projectName);
  await downloadGitRepo(api, dest);
};

  • 3.tips:download-git-repo不是promise对象,可以用util来对异步promise化,然后就可以愉快的使用async、await了
const { promisify } = require('util');
let downloadGitRepo = require('download-git-repo');
// 转为promise对象
downloadGitRepo = promisify(downloadGitRepo);

五、收集用户数据,生成package.json

const path = require('path');
const tools = require('./tools.js');
const fs = require('fs');
const { setChoices } = tools;

const setObj = async (param, projectName) => {
  const optionObj = {
    version: '1.0.0',
    name: projectName,
  };
  const defaultVal = optionObj[param] || '';
  const tempObj = {
    type: 'input',
    name: param,
    message: param,
    default: defaultVal,
  };
  const tempResult = await setChoices(tempObj);
  return tempResult;
};

const result = async projectName => {
  const file = path.resolve(process.cwd(), projectName + '/package.json');
  let data = fs.readFileSync(file, 'utf-8');
  const dataObj = JSON.parse(data);
  dataObj.version = await setObj('version');
  dataObj.author = await setObj('author');
  dataObj.name = await setObj('name', projectName);
  data = JSON.stringify(dataObj);
  fs.writeFileSync(file, data);
};
module.exports = result;

六、发布到npm库

  • 1.完成之后,npm login登录npm;
  • 2.npm publish发布到npm库。
  • 注意:
    • 1.发布前查是否已存在同名包;
    • 2.有淘宝镜像的切换回官方。
    • 3.每回发布需要更改version
  • tips:
    • 可以下载nrm来管理自己的npm源

2021-10-12-15-56-43.png