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

javascript/jquery

浏览数:105

2019-10-3

AD:资源代下载服务

手动新建项目实在有点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)等等,具体也要看业务需要。当然写一个脚手架可以大大规范项目的创建。
看到这里要是觉得还可以,别忘了点个赞哦~

作者:aaron_lawliet