前端工程化
本阶段主要以工程化为主题,分别从脚手架、自动化、模块化、规范化四个角度介绍前端工程化具体如何实践,以此应对复杂应用的开发过程,提高开发效率,降低维护成本,从而更适应大前端时代下的前端开发工作。
一.开发脚手架与自动化构建工作流封装
1.1 工程化概述
前端开发面临的问题:
1.想使用ES6+新特性,但是有兼容性问题
2.想使用Less/Sass/PostCss增强CSS的编程性时,运行环境不能直接支持
3.想要使用模块化的方式提高项目的可维护性时,运行环境不能直接支持
4.部署上线前需要手动压缩代码及资源文件,部署过程需要手动上传代码到服务器
5.多人协同开发时,无法硬性统一大家的代码风格.pull回来的代码质量无法得到保证
6.部分功能开发时,需要等待后端服务器接口提前完成才能去做具体的编码
1.2 脚手架工具
前端工程化主要解决的问题:
1.传统语言或语法的弊端
2.无法使用模块化/组件化
3.重复的机械式工作
4.代码风格统一,质量保证
5.依赖后端服务接口支持
6.整体依赖后端项目(强依赖)
1.3 一个项目过程中工程化的表现
一切以提高效率,降低成本,质量保证为目的的手段都属于工程化
整个前端项目流程所涉及到的工程化
1.4 工程化不等于某个工具
工具并不是工程化的核心,工程化是对项目的一种规划和架构.而工具只是落地这种架构的手段.
1.5 工程化与Node.js
工程化主要由node js强力推动,它主要内容涉及到已下几点
- 脚手架工具开发
- 自动化构建系统
- 模块化打包
- 项目代码规范化
- 自动化部署
二.脚手架工具
2.1 脚手架工具概要
脚手架的本质作用是创建项目基础结构,提供项目规范和相同的约定,比如
- 相同的组织结构
- 相同的开发范式
- 相同的模块依赖
- 相同的工具配置
- 相同的基础代码
IDE创建项目的过程就是一个脚手架的工作流程,如Android Studio或者VS Studio等,本文主要通过以下几点系统学习脚手架工具
- 脚手架的作用
- 常用的脚手架工具
- 通用脚手架工具剖析
- 开发一款脚手架
2.2 常用脚手架工具
目前市场上已经有很多脚手架工具了,但大多数都是为了特例项目类型服务的,它们都是根据信息创建对应的项目基础结构.例如
- React项目中的create-react-app
- Vue项目中的vue-cli
- Angular项目中的angular-cli
还有一类是以构建项目为目标,以***Yeoman***为代表的通用型项目脚手架工具,它可以根据一个模板生产一个对应的项目结构,这种类型的脚手架一般都比较灵活而且很容易扩展.
还有一类也很具有代表性叫Plop***,它们主要用于在项目开发过程*中去创建一些特定类型的文件,例如创建一个组件/模块所需要的文件
2.3 Yeoman简介
Yeoman 是一种老牌,高效,灵活的Web 应用脚手架搭建系统,使用Yeoman可以搭配任意一种类型的generator,我们可以通过创建自己的generator去打造一款属于自己的脚手架.但是Yeoman它过于灵活以至于许多基于框架开发的人眼中认为它不够专注,但这并不妨碍我们去学习它.
2.4 Yeoman基础使用
- 在全局范围安装yo:yarn global add yo
- 安装对应的generator:yarn global add generator-node
- 通过yo运行generator:yo node
- 下载需要的generator:yarn add generator-webapp
- yo webapp
2.5 Sub Generator子集生成器
当需要在已生成好的项目下再生成一些文件,就可以用到子集生成器Generator
- yo node:cli
- yarn link
- yarn
- my-module --help
2.6 创建Generator模块
-
cd generator-sample
-
yarn add yeoman-generator
-
在yeoman-generator下生成 generators/app/index.js文件
//index.js文件作为generators的核心入口
//需要导出一个继承 yeoman-generator的类型
//yeoman-generator在工作时会自动调用我们在此类型中定义的一些生命周期方法
//我们在这些方法中可以通过调用父类提供的一些工具方法实现一些功能,如文件写入
const Generator = require('yeoman-generator')
module.exports = class extends Generator {
writing(){
//yeoman 自动在生成文件阶段调用此方法
//我们这里尝试往项目目录中写入文件
this.fs.write(
this.destinationPath('temp.txt'),
Math.random().toString()
)
}
}
-
yarn link
-
cd my-proj
-
yo sample
2.7根据模板创建文件
相对于手动创建每一个文件,模板的方式大大提高了效率
在yeoman-generator下生成 generators/app/templates/foo.txt文件 写入如下内容
这是foo.txt文件的内容 它是一个模板文件
内部可以使用EJS模板标记输出数据
例如:<%= title %>
其他的EJS语法也支持
<% if (success) { %>
哈哈哈
<% }%>
在yeoman-generator下生成 generators/app/index.js文件 写入如下内容
const Generator = require('yeoman-generator')
module.exports = class extends Generator {
writing(){
//通过模板方式写入文件到目标目录
//模板文件路径
const tmpl = this.templatePath('foo.txt')
//输出目标路径
const output = this.destinationPath('foo.txt')
//模板数据上下文
const context = {title:'Hello conor~',success:false}
this.fs.copyTpl(tmpl,output,context)
}
}
- yarn link
- cd my-proj
- yo sample
2.8 接收用户输入
对于模板中的动态数据,例如项目的名称和标题一般使用命令行交互的方式去询问试用者从而得到.可以通过generator中的prompting实现.
const Generator = require('yeoman-generator')
module.exports = class extends Generator {
prompting () {
//在此方法中可以调用父类的prompt()方法发出对用户的命令行询问
return this.prompt([{
type:'input',
name:'name',
message:'Your project name',
default:this.appname //生成项目目录名称
}])
.then(answers=>{
//answers=>{name:'user input value'}
this.answers = answers
})
}
writing(){
//模板文件路径
const tmpl = this.templatePath('bar.html')
//输出目标路径
const output = this.destinationPath('bar.html')
//模板数据上下文
const context = this.answers
this.fs.copyTpl(tmpl,output,context)
}
}