教你从零开始搭建一款前端脚手架工具,做了6年前端开发

77 阅读5分钟

最后

你要问前端开发难不难,我就得说计算机领域里常说的一句话,这句话就是『难的不会,会的不难』,对于不熟悉某领域技术的人来说,因为不了解所以产生神秘感,神秘感就会让人感觉很难,也就是『难的不会』;当学会这项技术之后,知道什么什么技术能做到什么做不到,只是做起来花多少时间的问题而已,没啥难的,所以就是『会的不难』。

我特地针对初学者整理一套前端学习资料

前端路线图

vue.js的36个技巧 开源分享:docs.qq.com/doc/DSmRnRG…

入口文件

====

首先建立项目,在package.json里面写入依赖并执行npm install

"dependencies": {

"chalk": "^1.1.3",

"co": "^4.6.0",

"co-prompt": "^1.0.0",

"commander": "^2.9.0"

}

在根目录下建立\bin文件夹,在里面建立一个无后缀名的scion文件。这个bin\scion文件是整个脚手架的入口文件,所以我们首先对它进行编写。

首先是一些初始化的代码:

#!/usr/bin/env node --harmony 'use strict' // 定义脚手架的文件路径 process.env.NODE_PATH = __dirname + '/../node_modules/' const program = require('commander') // 定义当前版本 program .version(require('../package').version ) // 定义使用方法 program .usage('')

从前文的架构图中可以知道,脚手架支持用户输入4种不同的命令。现在我们来写处理这4种命令的方法:

program

.command('add')

.description('Add a new template')

.alias('a')

.action(() => {

require('../command/add')()

})

program

.command('list')

.description('List all the templates')

.alias('l')

.action(() => {

require('../command/list')()

})

program

.command('init')

.description('Generate a new project')

.alias('i')

.action(() => {

require('../command/init')()

})

program

.command('delete')

.description('Delete a template')

.alias('d')

.action(() => {

require('../command/delete')()

})

commander的具体使用方法在这里就不展开了,可以直接到官网去看详细的文档。

最后别忘了处理参数和提供帮助信息:

program.parse(process.argv)

if(!program.args.length){

program.help()

}

完整的代码请看这里

使用node运行这个文件,看到输出如下,证明入口文件已经编写完成了。

Usage: scion

Commands:

add|a Add a new template

list|l List all the templates

init|i Generate a new project

delete|d Delete a template

Options:

-h, --help output usage information

-V, --version output the version number

处理用户输入

======

在项目根目录下建立\command文件夹,专门用来存放命令处理文件。

在根目录下建立templates.json文件并写入如下内容,用来存放模版信息:

{"tpl":{}}

添加模板

进入\command并新建add.js文件:

'use strict' const co = require('co') const prompt = require('co-prompt') const config = require('../templates') const chalk = require('chalk') const fs = require('fs') module.exports = () => { co(function *() { // 分步接收用户输入的参数 let tplName = yield prompt('Template name: ') let gitUrl = yield prompt('Git https link: ') let branch = yield prompt('Branch: ') // 避免重复添加 if (!config.tpl[tplName]) { config.tpl[tplName] = {} config.tpl[tplName]['url'] = gitUrl.replace(/[\u0000-\u0019]/g, '') // 过滤unicode字符 config.tpl[tplName]['branch'] = branch } else { console.log(chalk.red('Template has already existed!')) process.exit() } // 把模板信息写入templates.json fs.writeFile(__dirname + '/../templates.json', JSON.stringify(config), 'utf-8', (err) => { if (err) console.log(err) console.log(chalk.green('New template added!\n')) console.log(chalk.grey('The last template list is: \n')) console.log(config) console.log('\n') process.exit() }) }) }

删除模板

同样的,在\command文件夹下建立delete.js文件:

'use strict' const co = require('co') const prompt = require('co-prompt') const config = require('../templates') const chalk = require('chalk') const fs = require('fs') module.exports = () => { co(function *() { // 接收用户输入的参数 let tplName = yield prompt('Template name: ') // 删除对应的模板 if (config.tpl[tplName]) { config.tpl[tplName] = undefined } else { console.log(chalk.red('Template does not exist!')) process.exit() } // 写入template.json fs.writeFile(__dirname + '/../templates.json', JSON.stringify(config), 'utf-8', (err) => { if (err) console.log(err) console.log(chalk.green('Template deleted!')) console.log(chalk.grey('The last template list is: \n')) console.log(config) console.log('\n') process.exit() }) }) }

罗列模板

建立list.js文件:

'use strict' const config = require('../templates') module.exports = () => { console.log(config.tpl) process.exit() }

构建项目

====

现在来到我们最重要的部分——构建项目。同样的,在\command目录下新建一个叫做init.js的文件:

'use strict' const exec = require('child_process').exec const co = require('co') const prompt = require('co-prompt') const config = require('../templates') const chalk = require('chalk') module.exports = () => { co(function *() { // 处理用户输入 let tplName = yield prompt('Template name: ') let projectName = yield prompt('Project name: ') let gitUrl let branch if (!config.tpl[tplName]) { console.log(chalk.red('\n × Template does not exit!')) process.exit() } gitUrl = config.tpl[tplName].url branch = config.tpl[tplName].branch // git命令,远程拉取项目并自定义项目名 let cmdStr = git clone gitUrl{gitUrl} {projectName} && cd {projectName} && git checkout {branch} console.log(chalk.white('\n Start generating...')) exec(cmdStr, (error, stdout, stderr) => { if (error) { console.log(error) process.exit() } console.log(chalk.green('\n √ Generation completed!')) console.log(\n cd ${projectName} && npm install \n) process.exit() }) }) }

可以看到,这一部分代码也非常简单,关键的一句话是

let cmdStr = git clone ${gitUrl} ${projectName} && cd ${projectName} && git checkout ${branch}

它的作用正是从远程仓库克隆到自定义目录,并切换到对应的分支。熟悉git命令的同学应该明白,不熟悉的同学是时候补补课啦!

全局使用

====

为了可以全局使用,我们需要在package.json里面设置一下:

"bin": {

"scion": "bin/scion"

},

本地调试的时候,在根目录下执行

npm link

即可把scion命令绑定到全局,以后就可以直接以scion作为命令开头而无需敲入长长的node scion之类的命令了。

现在我们的脚手架工具已经搭建好了,一起来尝试一下吧!

最后

一个好的心态和一个坚持的心很重要,很多冲着高薪的人想学习前端,但是能学到最后的没有几个,遇到困难就放弃了,这种人到处都是,就是因为有的东西难,所以他的回报才很大,我们评判一个前端开发者是什么水平,就是他解决问题的能力有多强。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

分享一些前端面试题以及学习路线给大家