从0-1实现一个前端脚手架

从0-1实现一个前端脚手架

一,为什么需要脚手架?

脚手架本质就是一个工具,作用是能够让使用者专注于写代码,它可以让我们只用一个命令就生成一个已经配置好的项目,而不用我们再花时间去配置和安装相关依赖,可以在很大程度上提升我们的开发效率。比如我们常用的create-vuecreate-react-app就是脚手架,很多大厂也都有自己的脚手架。

二,一个脚手架应该具备哪些功能?

我们以vue官方的脚手架create-vue为例来分析下一个脚手架应该具备哪些功能?

  1. 运行命令创建项目

    npm create vue@latest
    
  2. 用户根据自己需要选择一些配置项
    在这里插入图片描述

  3. 根据选择的配置项会生成一个模版项目

在这里插入图片描述

通过分析create-vue,我们可以知道,一个脚手架如果想要创建一个项目,最少要有以下两点功能:

  1. 可以通过命令行和用户交互
  2. 根据交互的结果去生成对应的模版项目

三,脚手架实现

初始化项目:

  1. 执行如下初始化命令
mkdir diy-cli   //创建一个文件夹
cd    diy-cli   //进入这个文件夹
npm   init -y   //npm初始化
  1. 在根目录下创建bin/index.js文件作为入口文件,并添加如下代码
#!/usr/bin/env node
console.log('diy-cli')
  1. 在package.json中添加bin字段
"bin": {
  "diy-cli": "/bin/index.js"
}
  1. 在根目录下执行npm link将项目链接到本地环境,就可以实现diy-cli命令全局调用

  2. 运行diy-cli并查看控制台输出

相关依赖

实现一个脚手架,通常会用到以下依赖包

talk is cheap, show me the code
#!/usr/bin/env node
const inquirer = require('inquirer');
const { program } = require('commander');
const figlet = require('figlet');
const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const gitClone = require('git-clone');
const ora = require('ora');

const projectList = {
  'vue': 'git@github.com:diy-cli/vue-template.git',
  'react': 'git@github.com:diy-cli/react-template.git',
  'react&ts': 'git@github.com:diy-cli/react-template-ts.git',
  'vue&ts': 'git@github.com:diy-cli/vue-template-ts.git',
}

// 修改帮助信息的首行展示
program.usage('<command> [options]')
// 版本号
program.version(`v${require('../package.json').version}`)
// 艺术字展示
program.on('--help', function () {
  console.log(
    figlet.textSync('kfc vme50', {
      font: 'Ghost',
      horizontalLayout: 'default',
      verticalLayout: 'default',
      width: 100,
      whitespaceBreak: true
    })
  )
});

// 创建项目的命令
program
  .command('create <app-name>')
  .description('创建新项目')
  .option('-f, --force', '如果创建的目录存在则强制删除')
  .action(async function (name, option) {
    const cwd = process.cwd();
    const targetPath = path.join(cwd, name);
    // 如果文件夹存在
    if (fs.existsSync(targetPath)) {
      if (option.force) {
        fs.remove(targetPath)
      } else {
        const res = await inquirer.prompt([
          {
            name: 'action',
            type: 'list',
            message: '是否覆盖已有文件夹?',
            choices: [
              {
                name: 'YES',
                value: true
              },
              {
                name: 'NO',
                value: false
              }
            ]
          }
        ])
        if (!res.action) {
          return;
        } else {
          fs.remove(targetPath)
          console.log(chalk.red('已删除之前的文件夹'))
        }
      }
    }

    const res = await inquirer.prompt([
      {
        name: 'type',
        type: 'list',
        message: '请选择使用的框架',
        choices: [
          {
            name: 'Vue',
            value: 'vue'
          },
          {
            name: 'React',
            value: 'react'
          }
        ]
      },
      {
        name: 'ts',
        type: 'list',
        message: '是否使用ts项目',
        choices: [
          {
            name: 'YES',
            value: true
          },
          {
            name: 'NO',
            value: false
          }
        ]
      }
    ])
    const rep = res.type + (res.ts ? '&ts' : '');
    // 拉取项目模板
    const spinner = ora('download project template ing...').start();
    gitClone(
      projectList[rep],
      targetPath,
      {
        checkout: 'main'
      },
      (err) => {
        if (!err) {
          fs.remove(path.resolve(targetPath, '.git'));
          spinner.succeed('finished!');
          console.log('now run:')
          console.log(chalk.green(`\n  cd ${name}`))
          console.log(chalk.green('  npm install'))
          console.log(chalk.green(`  npm run ${res.type === 'react' ? 'start' : 'dev'}\n`))
        } else {
          spinner.fail(chalk.red('Failed to load the project template. Please obtain it again!'));
        }
      }
    )
  })

program.parse(process.argv)

四,发布

  1. 注册npm账号
  2. 在本地登录并发布
# 登录刚注册的账号
npm login

Username: 用户名
Password: 密码
Email: 注册邮箱
Enter one-time password: 一次性密码  邮箱会收到邮件

# 在我们脚手架的根目录下执行发布命令npm publish

注意:

  1. 登录和发包前一定要先查看npm的源,需要修改为https://registry.npmjs.org/
  2. 在发布时包名不能重复,所以先在线上搜索下看看有没有存在的包,如果出现403错误可能是包名和线上的包重复了,修改package.json中的name即可
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值