其他分享
首页 > 其他分享> > 如何快速实现自己的脚手架

如何快速实现自己的脚手架

作者:互联网

github: hxh-cli https://github.com/hxh2010/hxh-cli

安装: npm i hxh-cli -g

使用: hxh-cli create xxx(项目名称)

脚手架是什么?

脚手架可以简单的理解为是自动为我们创建项目基础文件的工具,总结它的作用有两点:

使用的包

{
  "dependencies": {
    "commander": "命令行工具",
    "inquirer": "命令交互",
    "ora": "显示loading动",
    "remove": "删除文件相关",
    "replace-in-file": "替换文件中的内容"
  }
}

开始

1. 添加 bin 入口

修改package.json的bin执行入口,

{
  "bin": {
    "hxh-cli": "./bin/www"
  }
}

“hxh-cli” 这个命令可以自己选择,然后在bin文件加创建名为www的文件,

#!/usr/bin/env node

console.log("www start")
require('../src/main')

然后在 src 下 创建 main 文件

const program = require('commander');

program
  .version('0.0.1')
  .parse(process.argv);

2. 添加其它命令

// 自定义命令
const myCommand = {
  create: {
    alias: 'c', //别名
    description: '创建一个项目', // 描述
    examples: [ // 示例
      'hxh-cli create <project-name>',
    ],
  },
  config: {
    alias: 'conf',
    description: '配置项目',
    examples: [
      'hxh config set <k> <v>',
      'hxh config get <k>',
    ],
  },
  '*': {
    alias: '',
    description: '命令未找到',
    examples: [],
  },
}

/**
 * Reflect.ownKeys() 类似 Object.keys() 的功能。它返回一个由目标对象自身的属性键组成的数组。
 * 可以返回包含 Symbol 属性在内的自有属性。Object.keys() 返回属性 key ,但不包含不可枚举的属性。
 */
Reflect.ownKeys(myCommand).forEach((action) => {
  program
    .command(action)
    .alias(myCommand[action].alias)
    .description(myCommand[action].description)
    .action(() => {
      if (action === '*') {
        console.log(myCommand[action].description);
      } else {
        console.log(action);
        console.log(process.argv);
        // 如果创建的时候添加了项目名称,则传入项目名称
        require(path.join(__dirname, action))(...process.argv.slice(3))
      }
    });
});

// 处理 help 命令,打印出 example
program.on('--help', () => {
  console.log('\nExamples');
  Reflect.ownKeys(myCommand).forEach(action => {
    myCommand[action].examples.forEach(example => {
      console.log(` ${example}`);
    });
  });
});

3. 根据上述 action 创建对应文件

在 src 下创建 create、config(这个作配置用,暂时没用)

// creare.js
const inquirer = require('inquirer');
const replace = require('replace-in-file');
const ora = require('ora');
const child_process = require('child_process');
const remove = require('remove');

const {spawn} = child_process; // 子进程
const spinner = ora('downloading template ...');

/**
 * clone 项目到指定临时文件夹
 * @param clonePath 传入项目名称作为文件夹名称
 * @param templateUrl git 仓库地址
 * @returns {Promise<unknown>} 下载完成返回
 */
const cloneToTempDir = (clonePath, templateUrl) => {
  // ...
};

/**
 * 全局替换项目名称并删除 .git 文件
 * @param projectName 项目名称
 * @param downloadPath 项目地址
 * @returns {Promise<void>} 完成后返回
 */
const editFileAndDelGit = async function ({projectName, downloadPath}) {
  // ...
};


module.exports = projectName => {
  // 有传入则作为默认项目名
  console.log(`传入的项目名:${projectName}`);

  const questions = [
    {
      type: 'input',
      name: 'projectName',
      message: 'projectName:(项目名称)',
      default: projectName || undefined,
      validate(val) {
        if (!val) {
          return '请输入项目名';
        }
        return true;
      },
    },
    {
      type: 'list',
      name: 'template',
      message: '请选择模板',
      choices: [{
        name: ' test1',
        value: 'test1',
      },
        {
          name: 'test2',
          value: 'test2',
        }],
    },
  ];

  inquirer.prompt(questions).then(answers => {
    // ...

    // 拷贝项目并编辑项目(主要编辑内部名称为项目名)
    cloneToTempDir(projectName, templateUrl).then(clonePath => {
      editFileAndDelGit({ projectName, downloadPath: clonePath }).then(() => {
        spinner.succeed();
      });
    });
  });
};

本地测试及发布

本地测试

npm link

发布

npm addUser
npm publish

标签:const,projectName,require,hxh,如何,action,console,脚手架,快速
来源: https://blog.csdn.net/qq316020201/article/details/118071889