ArthurYung / my-voice

分享&吐槽
2 stars 0 forks source link

@开发脚手架遇到的问题 #9

Open ArthurYung opened 5 years ago

ArthurYung commented 5 years ago

写在前面

前段打字员最开心的事情就是造轮子了。没错,能跑能跳的轮子,变着花样来造。
现如今的潮流中,不使用构建工具都不好意思打开编辑器,写啥库都想用上ts,加配置加特效duang duang的。
那么问题来了,喜欢写轮子的我,每次都要花一大堆时间去配置环境么?于是我萌生了开发一用于造轮子的脚手架的想法。

有兴趣的朋友欢迎来试一试。plugin-cli
另外感谢jrainlau大佬2年前的文章。教你从零开始搭建一款前端脚手架工具

为什么要用rollup来写插件

rollup在我心中是一款与时俱进轻便小巧的打包工具,bundle文件相当清爽,tree shaking的夹持下(webpack4 也支持,但不够精细)有效缩减文件体积并能保持良好的可读性,用来开发插件再优秀不过了。(react16使用rollup) 优点:

遇到的问题

1.删除.git文件报错

通过阅读vue-cli的源码,我选择了download-git-repo这个node包来clone我github上的脚手架模版文件,可是测试的时候会报错BUSYNESS
于是我找到了download-git-repo的源码,发现它在克隆仓库之后,使用rimraf这个包的同步方法来删除文件目录中的.git,而我的脚手架在克隆模版之后还会通过用户选择来修改模版的配置,所以会造成冲突。
于是我通过使用rimraf的异步删除重写了克隆模版的方法。

// clear.js

const fs = require('fs')
const rimraf = require('rimraf')
const path = require('path')
const chalk = require('chalk')

module.exports = (name, cb) => {
    const workspace = process.cwd();
    const target = path.resolve(workspace, name, '.git')
    if(fs.existsSync(target)){
        rimraf(target, {}, (err)=>{
            if(err)  console.log(chalk.bgRed('err!'))
            else cb()
        })
    }
}
// download.js
const spawn = require('child_process').spawn;

module.exports = (url, targetPath, cb) => {
    const git = 'git'
    const args = ['clone', '--depth', '1']
    args.push(url)
    args.push(targetPath)
    const process = spawn(git, args)
    process.on('close', (status) => {
        if (status == 0) {
            const _args = ['checkout', 'master'];
            const _process = spawn(git, _args, { cwd: targetPath });
            _process.on('close', function(_status) {
                if (_status == 0) {
                    cb && cb();
                } else {
                    cb && cb(new Error("'git checkout' failed with status " + _status));
                }
            });
        } else {
            cb && cb(new Error("'git clone' failed with status " + status));
        }
    })
}

2.windows系统下报错spawn ENOENT

为了更省心地使用脚手架,我在项目新建之后进行了自动install/add的过程,没想到这一步在windows系统下出了差错,原来在spawn下子进程找不到npm的path,需要使用npm.cmd。see error-spawn-npm-enoent

const command = tc ? 'tnpm' : (hasyarn ? 'yarn' : 'npm')
    const args = []
    if (!hasyarn) {
        args.push('install', '--loglevel', 'error')
    } else {
        args.push('add')
    }
    const child = spawn(/^win/.test(process.platform) ? `${command}.cmd` : command, args, {
        cwd: name,
        stdio: hasyarn ? 'pipe' : 'inherit'
    })