ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-06-20 16:58:00  阅读:262  来源: 互联网

标签:const projectName require hxh 如何 action console 脚手架 快速


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有