前端脚手架开发

脚手架是什么

创建项目基础结构,提供项目规范和约定。
在众多的项目中,我们发现他们总是有着

  • 相同的组织结构
  • 相同的开发范式
  • 相同的模块依赖
  • 相同的工具配置
  • 相同的基础代码

脚手架就是用来解决这一些重复问题的。

常用的脚手架工具

我们常见的脚手架工具大都是为了特定项目类型服务的,比如vue-cli,create-react-app,只能创建对应的特定项目类型。还有通用的脚手架工具Yeoman,较为灵活易扩展。(CLI一般指命令行界面)

Yeoman

Yeoman是一款创建现代化web引用的脚手架工具。老牌,通用,强大,相比vue-cli的特定,他有更多值得我们学习的地方。它可以通过我们自定义的generator,创建自己想要的项目。

Yeoman的使用

全局范围安装yo
cnpm install -g yo

安装对应的generator (这里以想创建node项目的脚手架为例)
cnpm install generator-node -g

通过yo运行generator
mkdir my-module
yo node

最后通过命令行交互填写项目结构,一些描述,作者什么的

Sub Generator

有时候我们只是在原有的项目上添加些配置文件,例如eslint配置文件,bable配置文件等,这些文件都有些基础代码,如果自己手动配的话也容易出错,这就需要生成器自动帮我们生成,这种需求就适合通过Sub Generator来实现。

cd my-module
yo node:readme
generator-node中的sub generator说明

并不是说有generator都有sub generator, 比如generator-vue就没有

总结常规使用yeoman的步骤

  1. 明确你的需求
  2. 找到合适的generator(通过yeoman官网找)
  3. 全局范围安装你找到的generator
  4. 通过Yo运行此generator
  5. 通过命令行交互填写项目结构
  6. 生成你所需要的项目结构

自定义generator,搭建自己的脚手架

比如vue官方的vue-cli,创建完成后只包含vue结构,如果我们还想集成vue-router,vuex,那我们就可以自行搭建自己的脚手架。

创建generator模块

generator本质上就是一个npm模块


generator基本结构

如果想添加Sub Generator,目录就如下


多了一个component子生成器

还有Generator的模块名称必须是generator-<name>
mkdir generator-sample && cd generator-sample

创建一个package.json
npm init

这个模块会为我们提供一个generator生成器的基类,基类中提供了一些工具函数,可以让我们写生成器的时候更加便捷
npm install yeoman-generator

按照上述图的目录标准,创建generators/app/index.js文件
// index.js
// 此文件作为 Generator 的核心入口
// 需要导出一个继承自 Yeoman Generator 的类型
// Yeoman Generator 在工作时会自动调用我们在此类型中定义的一些生命周期方法
// 我们在这些方法中可以通过调用父类提供的一些工具方法实现一些功能,例如文件写入

const Generator = require('yeoman-generator')
module.exports = class extends Generator {
  writing () {
    // Yeoman 自动在生成文件阶段调用此方法
    // 我们这里尝试往项目目录中写入文件
    this.fs.write( // 这个fs不是node模块的fs,这个更强大
      this.destinationPath('temp.txt'), // 绝对路径
      Math.random().toString() //填入随机数
    )
  }
}

这样一个简单的generator就完成了。

通过命令行把这个模块链接到全局范围,使之成为一个全局模块包
npm link
mkdir my-sample && cd my-sample
yo sample

=>生成文件啦

根据模版创建文件

大部分时候我们要创建的文件较多也较复杂,所以我们使用模版,可以更便捷一些

创建template/foo.txt
// foo.txt
这是一个模板文件
内部可以使用 EJS 模板标记输出数据
例如:<%= title %>

其他的 EJS 语法也支持

<% if (success) { %>
哈哈哈
<% }%>
writing () {
    // 通过模板方式写入文件到目标目录
    // 模板文件路径
    const tmpl = this.templatePath('foo.txt')
    // 输出目标路径
    const output = this.destinationPath('foo.txt')
    // 模板数据上下文
    const context = { title: 'Hello zce~', success: true }
    this.fs.copyTpl(tmpl, output, context)
}

html也同理

接收用户输入

通过prompting方法,接收命令行交互中用户输入的数据

prompting () {
        // Yeoman 在询问用户环节会自动调用此方法
        // 在此方法中可以调用父类的 prompt() 方法发出对用户的命令行询问
        return this.prompt([
          {
            type: 'input',
            name: 'name',
            message: 'Your project name',
            default: this.appname // appname 为项目生成目录名称
          }
        ])
        .then(answers => {
          // answers => { name: 'user input value' }
          this.answers = answers
        })
      }
// 在想使用的地方 this.answer.name

Vue-generator案例

开发一个vue-cli
https://gitee.com/ericzhouhang/generator-vue-demo

generator发布

generator本质上就是一个npm模块,所以就是发布一个npm模块
npm publish

Plop

一个小型前端脚手架工具,一般用来创建项目中的同类型文件

脚手架工作原理

启动它过后,它会自动的去询问你一些预设的问题,然后将你回答的结果,结合模版文件,生成项目的内容。 核心代码:

#!/usr/bin/env node
// Node CLI 应用入口文件必须要有这样的文件头
//意思是指定用node执行脚本文件。

// 脚手架的工作过程:
// 1. 通过命令行交互询问用户问题
// 2. 根据用户回答的结果生成文件

const fs = require('fs')
const path = require('path')
const inquirer = require('inquirer') // 命令行交互模块
const ejs = require('ejs')

inquirer.prompt([
  {
    type: 'input',
    name: 'name',
    message: 'Project name?'
  }
])
.then(anwsers => {
  // console.log(anwsers)
  // 根据用户回答的结果生成文件

  // 模板目录
  const tmplDir = path.join(__dirname, 'templates') // __dirname:当前模块的目录名
  // 目标目录
  const destDir = process.cwd() // Node.js 进程的当前工作目录。

  // 将模板下的文件全部转换到目标目录
  fs.readdir(tmplDir, (err, files) => {
    if (err) throw err
    files.forEach(file => {
      // 通过模板引擎渲染文件
      ejs.renderFile(path.join(tmplDir, file), anwsers, (err, result) => {
        if (err) throw err

        // 将结果写入目标文件路径
        fs.writeFileSync(path.join(destDir, file), result)
      })
    })
  })
})
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353