概述

前端工程化是应用软件工程的技术和办法来进行前端的开发流程、技术、工具、教训等规范化,标准化,次要目标是为了提高效率和降低成本。

目前,前端我的项目越来越复杂化和多元化,然而随着变动而来的就是如下问题:

  • 传统语言或语法有弊病。尽管ES6及后续版本提出很多解决方案,然而因为环境的反对水平不同,须要进行大量重复性的适配工作。
  • 无奈模块化,组件化。简略来说,模块化指的是将一个文件拆分成多个互相独立的小文件,应用的时候再依照肯定的规定加载和拼接。组件化是指将UI拆分成一个个性能独立繁多的结构单元。
  • 存在大量的反复的机械性工作。如我的项目的构建,公布等。
  • 代码格调不对立,无奈保证质量。
  • 重大依赖后端接口反对。
  • 其余问题。

前端工程化为上述问题提供了成熟的解决方案,作为使用者,能够更加关注业务逻辑的实现,也就进步了效率,升高了老本。

脚手架工具

创立我的项目的第一步就是利用脚手架工具创立我的项目模版,目前风行的框架均提供了脚手架工具,如react的create-react-app,vue的vue-cli。这些脚手架工具不仅构建了对立的我的项目构造,同时提供了语法转换、模块化组件化、代码格调查看、单元测试、主动构建部署等计划。

Yeoman是一种开源的脚手架工具,其相比vue-cli专门用于vue我的项目不同,其更加灵便,能够基于不同的generator生成不同的我的项目。因而本篇文章将从Yeamon动手,摸索如何搭建脚手架。

应用Yeoman创立我的项目

  • 装置yo: npm install -g yo。
  • 依据想要创立的我的项目类型应用相应generator,咱们创立一个webapp,因而应用generator-webapp:npm install -g generator-webapp(Yeoman提供了generator查找命令,可一键查找装置)。
  • 在我的项目根文件夹下执行:yo webapp。

创立自定义Generator

应用Yeoman创立自定义脚手架,就是创立generator。

  • 装置generator-generator: npm install generator-generator。

generator-generator是可用于生成generator模版,运行yo generator可创立模版我的项目,我的项目构造如下:

.├── generators/│   └── app/│       ├── index.js│       └── templates/│           └── dummyfile.txt├── .editorconfig├── .eslintignore├── .gitattributes├── .gitignore├── .travis.yml├── .yo-rc.json├── LICENSE├── README.md├── package.json└── __tests__/    └── app.js

次要逻辑在index.js中,templates文件夹蕴含所有模版文件。

  • index.js文件导出一个继承自Generator的类,其蕴含了一些配置,控制台交互,文件操作等办法。
const Generator = require('yeoman-generator');module.exports = class extends Generator {  // 执行控制台与用户的交互  prompting() {    const prompts = [      {        type: 'input',        name: 'name',        message: 'What is your Project Name?',        default: 'cus-project'      }    ];    return this.prompt(prompts).then(props => {      // 保留用户的输出或者抉择      this.props = props;    });  }  // 执行文件操作  writing() {    this.fs.copyTpl(      // 源文件      this.templatePath('dummyfile.txt'),      // 指标文件      this.destinationPath('test.txt'),      this.props    )  }  // 主动装置依赖  install() {    this.npmInstall();  }};

能够在模版文件中用<%=name %>应用用户props。

  • 将编写的包上传到npm,此处因为咱们是测试,能够应用:npm link。
  • 在须要创立我的项目的文件夹下执行yo customeGeneratorName(如咱们的我的项目名为generator-test,此处就应该是test)。

实现自定义脚手架工具

从自定义generator示例中能够看出,实现一个简略的脚手架次要是实现以下两个方面的内容:

  1. 实现与用户之间的交互(控制台交互)。
  2. 实现文件的模版替换和复制操作。

在实现自定义脚手架工具之前,得须要理解上面内容:

  • 如何在npm包中增加可执行文件?

在npm包的pakage.json文件中增加bin属性,bin的值是一个对象:

{    // 键表示命令,值示意在终端输出命令后执行的文件    "create-custom": "index.js"}

当我的项目中install这个包的时候,命令会注册到全局或者./node_modules/.bin/目录里。

在执行文件的结尾须要加上`#!/usr/bin/env node`,否则不会被辨认。
  • inquirer

inquirer用于疾速创立交互式命令行。其根本应用如下:

#!/usr/bin/env nodeconst inquirer = require('inquirer')// 设置问题inquirer.prompt([    {        type: 'input', // 问题类型        name: 'name', // 数据属性名        message: '名称', // 提示信息        default: 'Rogan' // 默认值    },    {        type: 'list',        name: 'data',        message: '抉择语言',        choices: [            {                name: 'javascript', value: 1            },            {                name: 'go', value: 2            }        ]    }]).then(answers => {    // 处理结果    console.log(answers)})

问题选项中的类型蕴含如下:

  1. input: 输出文本
  2. number: 输出数字
  3. confirm: 是否抉择 (y/n)
  4. list: 抉择列表
  5. rawlist: 带编号的抉择列表
  6. expand: 带缩写抉择列表
  7. checkbox: 多选
  8. password: 明码
  9. editor:文本编辑器
  • ejs模版语法

ejs是一种高效的嵌入式JavaScript模板引擎。

let ejs = require('ejs')ejs.render(`       抉择的语言有<%= languages.join(',')%>    `, {    languages: ['php', 'javascript']})
  • fs

fs是node内置的模块,用于文件的操作。

通过下面几个工具就能够实现简略的脚手架工具,实现目标:获取用户的抉择,依据抉择编译模版并生成我的项目。

在index.js文件中:

#!/usr/bin/env nodeconst inquirer = require('inquirer')const fs = require('fs')const ejs = require('ejs')const path = require('path')const choices = [    { name: 'javascript', value: 1 },    { name: 'php', value: 2 },    { name: 'go', value: 3 }]// 实现命令行交互inquirer.prompt([    {        type: 'checkbox',        name: 'lang',        message: '抉择语言',        choices    }]).then(answers => {    // 获取交互内容    const choiced = answers.lang.map(item => {        let lan = choices.find(l => l.value === item)        return lan.name    })    // 获取模版文件夹所在门路    const templatesDir = path.join(__dirname, 'templates')    // 获取以后命令行执行文件夹门路    const destDir = process.cwd()    // 读取模版文件夹下的所有文件    fs.readdir(templatesDir, function (err, files) {        if (err) {            throw err        }        files.forEach(file => {            // 编译模版文件            ejs.renderFile(path.join(templatesDir, file), { lang: choiced }, (err, result) => {                if (err) throw err                // 将编译后的内容拷贝到以后命令行执行文件夹下                fs.writeFileSync(path.join(destDir, file), result)            })        })    })})

在模版index.html中:

<html>    <header></header>    <body>        <div>            用户抉择: <%= lang.join(',')%>        </div>    </body></html>

应用plop

和Yeoman不同,plop是一个在我的项目内应用的,能够疾速创立指定格式文件的脚手架工具,如在vue编程过程中,每次创立.vue文件,均须要在文件中手动输出template,script,style三个节点,能够利用此工具一键生成文件,缩小大量的反复工作。
应用步骤如下:

  • 装置依赖包 npm install --save-dev plop
  • 在根目录下创立plopfile.js文件,该文件可用于注册命令。
module.exports = function (plop) {    // 设置生成器    plop.setGenerator("create-vue-file", {        description: "创立vue模版文件",        // 命令行交互        prompts: [            {                type: 'input',  // 交互类型                name: 'name',   // 参数名称                message: '请输出vue文件名称', // 交互提醒                default: 'VueFile'            },            {                type: 'input',                name: 'path',                message: '请输出文件创建目录'            }        ],        // 交互实现后执行的动作        actions: [            {                type: 'add', // 动作类型: 示意增加文件                path: '{{ path }}/{{ name }}.vue', // 依据用户输出获取文件门路                templateFile: 'templates/vue.hbs' // 模板文件地址, 应用hbs文件            }        ] // 执行操作    })}
  • 增加模版文件,在templates文件加下增加vue.hbs模版文件
<template>    <div class="{{name}}-container">    </div></template><script>    export default {        name: {{ name }}    }</script><style>    .{{name}}-container {            }</style>
  • 增加npm scripts

在package.json文件的scripts属性下增加:"plop": "plop"

  • 执行命令

在命令行执行: npm run plop create-vue-file。
依据提醒输出文件名和文件门路,最终会生成文件如下: