自己手动撸一个前端脚手架

51次阅读

共计 2974 个字符,预计需要花费 8 分钟才能阅读完成。

手动新建项目实在有点 low
怎么装逼?
当然是自己写一个脚手架。

基本流程

写脚手架基本都是这么个流程,当然可能一些复杂的定制化项目小步骤比较多,那就按需再做额外考虑
1. 输入基本信息
2. 下载基础代码
3. 对基础代码进行一定的修改
4. 额外的事

需要的库

// nodejs 相关
const fs = require('fs');
const path = require('path');

// 输入基本配置
const inquirer = require('inquirer');

// 通过 git 下载基础代码
const download = require('download-git-repo');

// 对基础代码的配置文件进行修改
const handlebars = require('handlebars');

// 运行子程序,很有用
const ora = require('ora');
const {spawn} = require('child_process');

// 美化打印信息,可以不用
const chalk = require('chalk');
const symbols = require('log-symbols');

一、输入基本信息

使用 inquirer 这个库
引到使用者配置基本的项目信息,比如

有各种可以输入的方式,比如直接输入、选项、是否等等类型,建议查看官方文档
或者自行搜索译文
范例:

inquirer.prompt([
    {
        type: 'input',
        name: 'year',
        message: '请输入项目年份,比如 2019(插件请输入"plugins")',
        default: now.getFullYear()}, {
        type: 'input',
        name: 'name',
        message: '请输入项目名称,比如 0702projectname',
        default: `${String(now.getMonth() + 1).padStart(2, '00')}${now.getDate()}-projectName`
    }, {
        type: 'list',
        name: 'platform',
        message: 'PC 端项目还是 wap 端项目?',
        choices: ['pc', 'wap'],
        default: 0
    }, {
        type: 'input',
        name: 'author',
        message: '请输入作者名称',
        default: 'author_name'
    }, {
        type: 'confirm',
        name: 'autoInitialize',
        message: '是否自动安装依赖?'
    }, {
        type: 'list',
        name: 'packageManager',
        message: '使用哪种包管理工具?',
        choices: ['npm', 'yarn'],
        default: 0
    }
]).then((answers) => {const { year, name} = answers;
    const projectBasePath = year == 'plugins' ? `project/${year}/${name}` : `project/zt/${year}/${name}`;

    // 项目已存在则退出
    if (fs.existsSync(projectBasePath)) {return console.log(symbols.error, chalk.red('项目已存在'));
    }
    
    // 根据配置的项目名创建目录
    
    // 下载依赖

})

二、下载依赖

使用 ora 来下载依赖,ora 是一个运行子程序的库,详细使用方法请见官方文档
这个官方文档好像不太友好,下面通过代码简单叙述一下 ora 的作用:

const ora = require('ora');
const download = require('download-git-repo');

// 使用子程序下载基础代码
// 子程序的优点是,执行代码更灵活,也可以不在当前目录下执行命令
// 缺点是不会显示子程序里执行的代码的打印信息
function downloadTemplate(projectBasePath, answers) {const spinner = ora('正在下载模板……').start(); // 这里设定子程序名字为 spinner,并开始子程序
    download( // 在子程序执行下载,下载过程的信息不会在当前的命令行里打印出来,因为是子程序
        'git.koolearn-inc.com:guonei/koo-guonei-static-basecode',
        projectBasePath,
        {clone: true},
        (err) => {if (err) {spinner.fail(); // 子程序运行失败
                
                // 打印信息。symbols.error 和 chalk.red 都是美化作用,不加也无所谓
                console.log(symbols.error, chalk.red(` 获取 git@${gitRepo}.git 时出错:\n${err}`));
            } else {spinner.succeed(); // 子程序运行成功
            }
        }
    )
}

三、根据配置信息,对基础代码做一些修改

这部分我一般会修改 package.json 文件配合 webpack 打包工具,来做不同的打包处理
考虑到每个项目的需求情况相差比较大,所以不做具体的介绍
仅提供几个思路

1. 使用 fs 读取文件进行修改

2. 使用库 handlebars 来对 package 文件进行修改

四、额外的事

比如自动下载依赖,建议使用 ora 子程序下载依赖
关于 spawn,请参考 nodejs 的官方文档

const ora = require('ora');
const {spawn} = require('child_process');

// 安装依赖
function yarnInstall(dir, pm) {const spinner = ora('正在安装依赖……').start();
    const sp = spawn(pm, ['install'], {cwd: path.resolve(__dirname, '../' + dir),
        shell: /^win/.test(process.platform) // windows 环境要加这一句,否则会报错
    })

    sp.on('message', msg => {console.log(msg.toString());
    })
    sp.stdout.on('data', (data) => {console.log(data.toString());
    });

    sp.on('close', code => {if (code !== 0) {spinner.fail();
            return console.log(chalk.red(` 安装失败,退出码 ${code}`))
        }
        spinner.succeed();
        console.log(chalk.green(` 下载依赖成功~ 请执行 cd ${dir}`))
    })
}

五、其他

关于自动下载依赖:

最开始是想通过代码改变主程序当前指向的地址,后来确定这是不可能的。目前想到的自动下载依赖的方法只有子程序

六、写在最后

这只是一个简单的项目脚手架而已,复杂的脚手架其实也是在此基础上考虑了更多的情况(多得多的情况),比如需要依赖的额外的库、基于什么前端框架开发 (vue/react/jquery) 等等,具体也要看业务需要。当然写一个脚手架可以大大规范项目的创建。
看到这里要是觉得还可以,别忘了点个赞哦~

正文完
 0