从0到1学会开发前端脚手架

时间:2022-12-21 18:55:58

【课程简介】

在前端开发中经常会用到create-vue, create-react-app这类脚手架,它可以帮助我们快速生成一个配置化的项目,提高开发效率。现在很多大厂都有自己研发的脚手架,掌握脚手架的使用,并且自己能开发脚手架,能够让大家前端之路走得更远。本次课程将会解析脚手架实现原理,从0到1实现一个前端脚手架,让大家轻松掌握!

【主讲内容】

1. 脚手架实现原理思路解析

2.命令行开发常用第三方模块

3.从0到1码出一个前端脚手架

【教程推荐】从0到1开发前端脚手架

为什么需要脚手架?

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

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

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

1.运行命令创建项目

➜ npm create vue@latest

2.用户根据自己需要选择一些配置项

从0到1学会开发前端脚手架

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

从0到1学会开发前端脚手架

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

1.可以通过命令行和用户交互

2.根据交互的结果去生成对应的模版项目

脚手架实现

初始化项目

1.执行如下初始化命令

➜ mkdir kfc-vme50
➜ cd kfc-vme50
➜ npm init -y

2.在根目录下创建bin/index.js文件作为入口文件,并添加如下代码

#!/usr/bin/env node
console.log('肯德基疯狂星期四v我50')

3.在package.json中添加bin字段

"bin": {
  "kfc-vme50": "/bin/index.js"
}

4.在根目录下执行npm link将项目链接到本地环境,就可以实现kfc-vme50命令全局调用

5.运行kfc-vme50并查看控制台输出

从0到1学会开发前端脚手架

相关依赖

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

commander:命令行处理工具

chalk:命令行输出美化工具

inquirer:命令行交互工具

ora:终端loading美化工具

git-clone:下·载项目模版工具

figlet:终端生成艺术字

fs-extra:用来操作本地目录

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:kfc-vme50/vue-template.git',
  'react': 'git@github.com:kfc-vme50/react-template.git',
  'react&ts': 'git@github.com:kfc-vme50/react-template-ts.git',
  'vue&ts': 'git@github.com:kfc-vme50/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('正在加载项目模板...').start();
    gitClone(
      projectList[rep],
      targetPath,
      {
        checkout: 'main'
      },
      (err) => {
        if (!err) {
          fs.remove(path.resolve(targetPath, '.git'));
          spinner.succeed('项目模板加载完成!');
          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('项目模板加载失败,请重新获取!'));
        }
      }
    )
  })

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即可