概述
前端工程化是应用软件工程的技术和办法来进行前端的开发流程、技术、工具、教训等规范化,标准化,次要目标是为了提高效率和降低成本。
目前,前端我的项目越来越复杂化和多元化,然而随着变动而来的就是如下问题:
- 传统语言或语法有弊病。尽管 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 示例中能够看出,实现一个简略的脚手架次要是实现以下两个方面的内容:
- 实现与用户之间的交互(控制台交互)。
- 实现文件的模版替换和复制操作。
在实现自定义脚手架工具之前,得须要理解上面内容:
- 如何在 npm 包中增加可执行文件?
在 npm 包的 pakage.json 文件中增加 bin 属性,bin 的值是一个对象:
{
// 键表示命令,值示意在终端输出命令后执行的文件
"create-custom": "index.js"
}
当我的项目中 install 这个包的时候,命令会注册到全局或者./node_modules/.bin/ 目录里。
在执行文件的结尾须要加上 `#!/usr/bin/env node`,否则不会被辨认。
- inquirer
inquirer 用于疾速创立交互式命令行。其根本应用如下:
#!/usr/bin/env node
const 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)
})
问题选项中的类型蕴含如下:
- input: 输出文本
- number: 输出数字
- confirm: 是否抉择 (y/n)
- list: 抉择列表
- rawlist: 带编号的抉择列表
- expand: 带缩写抉择列表
- checkbox: 多选
- password: 明码
- editor: 文本编辑器
- ejs 模版语法
ejs 是一种高效的嵌入式 JavaScript 模板引擎。
let ejs = require('ejs')
ejs.render(`
抉择的语言有 <%= languages.join(',')%>
`, {languages: ['php', 'javascript']
})
- fs
fs 是 node 内置的模块,用于文件的操作。
通过下面几个工具就能够实现简略的脚手架工具,实现目标:获取用户的抉择,依据抉择编译模版并生成我的项目。
在 index.js 文件中:
#!/usr/bin/env node
const 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。
依据提醒输出文件名和文件门路,最终会生成文件如下: