1、前端工程化 概述
前端工程化: 是指遵循一定标准和规范,通过工具提高开发效率、降低成本一种手段;被广泛的关注和探讨,究其原因是:前端功能要求不断提高,业务逻辑日夜复杂;从传统的网站、H5、小程序;
1、前端开发过程中面临的问题:
- 想要使用ES6+ 新特性,但是兼容有问题
- 想要使用Less、Sass、PostCSS增强 CSS的编程性,但是运行环境不能直接支持
- 想要使用模块化的方式提高项目的可维护性,但运行环境不能直接支持
- 部署上线前需要手动压缩到代码及资源文件,部署过程需要手动上传代码到服务器
- 多人协作开发,无法硬性统一大家的代码风格,从仓库中pull回来的代码质量无法保证
- 部分功能开发时需要等待后端服务接口提前完成
2、前端工程主要解决的问题:
- 传统语言或语法的弊端
- 无法使用模块化/组件化
- 重复的机械式工作
- 代码风格统一、质量保证:
- 依赖后端服务接口支持
- 整体以来后端项目
3、前端工程化的表现
整体的角度: 从项目的创建-》编码-》预览-》提交-〉部署,每个环节都可以通过工程化的方式提高效率;具体来说,
- 创建项目的时候,可以是使用脚手架工具自动帮我们完成基本结构的搭建;
创建项目结构和创建特定类型文件 - 编码: 借助于
工程化的工具自动化帮我们做一些:格式化代码、校验代码风格、编译、构建、打包 - 预览/测试:传统的预览环节姐注意阿帕奇提高web的基础服务,无法提供热更新的服务;现在可以使用:Web Sever,Mock,
- 提交: 可以使用Git Hooks/Lint- staged/持续集成的方式自动化在代码提交之前检查项目质量和风格,确保不会把有问题的代码提交上去,解决了从仓库pull下来有问题的代码
- 部署:自动发布,CI/CD,避免人为手动操作的错误因素
4、前端工程化的表现细节
工程化 并不等于 某个工具
工程化的核心:应该是对整体项目的 规划和架构,而工具只是用来帮我们落地实施规划和架构的一种手段;
- 成熟的工程化工具:
属于特定类型的项目(是工程化的集成),官方给出的集成式工程化方案,比如:vue-cli不仅仅帮我们创建了项目,更多的是约定了vue项目是什么结构,提供了一些工具:热更新,代码风格校验;
5、落实前端工程化的5个维度来说:
- 脚手架工具开发
- 自动化构建系统
- 模块化打包
- 项目代码规范化
- 自动化部署
2、脚手架 工具
1、脚手架的本质作用
本质作用: 自动的创建项目接基础文件结构的工具、提供项目规范和约定; 相同约定包含:
- 相同的组织结构
- 相同的开发范式
- 相同的模块依赖
- 相同的工具配置
- 相同的基础代码
总结:终以上的相同约定,这样一来搭建新项目时,会出现
大量的重复工作要做,脚手架工具用来解决这样的问题(解决项目的复杂工具),可以通过脚手架工具快速搭建特定类型的项目骨架,基于这个骨架开始工作;
举例:IDE创建项目的过程就是一个脚手架的工作流程;
前端的脚手架一般不会集成在某一个IDE中,以独立的工具存在;
2、常用脚手架的工具
- react -> create-react-app
- vue -> vue-cli
- angluar ->angluar-cli
这些工具无外乎就是
根据你提供的信息创建对应的项目基础结构;它们是适用于对自身所服务的框架项目;还有一类: - 以
Yeoman为代表的通用性项目脚手架工具,它们根据一套模版,生成一个对应项目结构,非常灵活、非常容易扩展; Plop: 用来在项目开发过程当中用于去创建特定类型的文件;
3、Yeoman介绍
定义: 官方定义是:创建现代化的web应用的脚手架工具;Yeoman 更像于一个脚手架运行的一个平台,我们可以通过Yeoman搭建不同类型的 Generator 去创建任何类型项目;我们通过Generator创建自己的项目,从而定制搭建自己的脚手架;Yeoman的优点同样也是它的缺点:在很多专注基于框架开发的人眼中,Yeoman过于通用不够专注,所以它们更愿意使用像vue-vli这类的脚手架;
4、Yeoman 基本使用
- 1、安装 Yeoman:
yarn global add yo - 2、安装对应的Generator,
搭建不同的 Generator 类型: 比如使用Generator- node,yarm g add generator-node - 3、使用yarn搭建项目: 新建项目的文件夹, 运行
yo node创建node项目, 选择项目的基础信息
5、Yeoman 之 Sub Genaerator
创建特定类型的文件,比如:es6, babel,等等,需要这个需求,可以使用Sub Genaerator,
- 安装:yo node:cli ,重写package.json文件,添加新的模块和配置,出现一个binde 配置:‘lib/cli.js’
- 将模块作为全局使用: yarn link ,可直接使用模块名执行项目
6、Yeoman 使用步骤总结
- 1、明确你的需求
- 2、找到合适的 Generator
- 3、全局范围安装找到 Generator
- 4、通过yo运行对应的 Generator
- 5、通过命令行交互填写选项
- 6、生成你所需要的项目结构
7、自定义的 Generator 之创建Generator
- 创建 Generator :就是NPM模块;
- Yeoman 的Generator 的名称必须是
generator-<name>,不会找不到该模块 - 安装 Generator: yarn add yeoman-generator的模块
- 创建自定义Generator文件夹: generator->app->index.js,在index.js导出一个继Yeoman Generator的类型;
7、根据模块创建文件
8、Vue Generator 案例
- 1、创建全新的Generator目录:mkdir generator-vue
- 2、yarn init , 初始化package.json
- 3、安装Yeoman的依赖, yarn add yeoman-enerator
- 4、新建Generator的主入口文件: generator->app->index.js,在index.js导出一个继Yeoman Generator的类型;
9、脚手架的工作原理
脚手架工具就是一个CLI应用。基本都是启动脚手架之后进行命令行交互,根据交互结果结合模板文件形成一个基础的项目结构。
1、开发一个小型的CLI
- mkdir sample-scaffolding
- cd sample-scaffolding
- yarn init --yes
2、打开 package.json 文件,添加一个 bin 字段。
"name": "sample-scaffolding",
"version": "1.0.0",
"main": "index.js",
"bin": "cli.js",
"license": "MIT"
}
3、然后创建这个 cli.js 文件
#!/usr/bin/env node
// Node CLI 应用入口文件必须要有这样的文件头
// 如果是 Linux 或者 macOS 系统下还学要修改此文件的读写权限
// 具体就是通过 chmod 755 cli.js 实现修改
console.log('cli working')
4、在命令行通过 yarn link的方式将这个模块link到全局
5、然后命令行运行:sample-scaffolding
6、使用inquirer进行命令行交互,安装yarn add inquirer
7、 脚手架的工作过程cli.js
//1、通过命令行交互询问用户问题
//2、根据用户回答的结果生成文件
const inquirer = require('inquirer');
inquirer.prompt([
{
type:'input',
name:'name',
message:'Project name'
}
]).then(answer=>{
console.log(answer);
})
8、 在命令行执行sample-scaffolding,能返回结果说明执行成功
9、 新建模板目录templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
<%= name %>
</title>
</head>
<body>
</body>
</html>
10、新建templates/style.css(第二个模板)
11、需要用到通过模板引擎渲染文件,所以安装模板引擎
yarn add ejs
12、创建一个新的文件目录demo
13、在新的文件目录命令行下执行sample-scaffolding,将会在demo目录下生成模板文件渲染出来的文件
14、简单案例完整代码:
#!/usr/bin/env node
// Node CLI 应用入口文件必须要有这样的文件头
// 如果是 Linux 或者 macOS 系统下还学要修改此文件的读写权限
// 具体就是通过 chmod 755 cli.js 实现修改
// console.log('cli working')
// 脚手架的工作过程:
// 1. 通过命令行交互询问用户问题
// 2. 根据用户回答的结果生成文件
// 使用 inquirer 在 node 中和用户进行命令行交互
// yarn add inquirer
const path = require('path')
const fs = require('fs')
const inquirer = require("inquirer")
const ejs = require("ejs")
inquirer.prompt([
{
type: 'input',
name: 'name',
message: 'Project Name?'
}
]).then(answers => {
// console.log(answers)
// 根据用户的回答结果解和模板生成文件
// 模板的目录
const tmpDir = path.join(__dirname, 'templates')
// 目标目录
const destDir = process.cwd()
// console.log(process.cwd()) // D:\workPlatform\demos\sample-scaffolding
// 将模板下的文件全部转换到目标目录
fs.readdir(tmpDir, (err, files) => {
if(err) throw err
files.forEach(file => {
// 通过模板引擎去渲染这些文件
ejs.renderFile(path.join(tmpDir, file), answers, (err, result) => {
if(err) throw err
// console.log(result)
// 将结果写入目标文件路径
fs.writeFileSync(path.join(destDir, file), result)
})
})
})
})
自动化构建
1、自动化简介
- 自动化:通过机器代替手工完成工作
- 构建: 转换,把一个东旭转换为另一个东西
- 开发行业当中的自动化构建:把开发阶段写出来的源代码自动化转换成生成阶段的可以运行的代码或者程序,一般把这个转换的过程叫做自动化构建工作流;
- 自动化构建工作流作用:
脱离运行环境兼容带来的问题;在开发阶段使用提高效率的语法、规范和标准; - 应用场景:
- 开发网页时:ECMAScirpt Next提高编码效率和质量
- Sass: 增强CSS的可编程性
- 模版引擎: 抽象HTML中重复的代码
- 自动化构建工具的作用: 构建转换那些不被支持的
特性;
2、实现自动化构建 NPM Script --- 构建简单的项目
- 安装 yarn add browser-sync --dev
- 在package.json中,
"scripts": {
"preserver": "yarn build",// 启动之前自动构建Sass文件
// 监听项目下文件的变化,自动同步到浏览器
"serve": "browser-sync --files \"css/*.css\"",
"start":"run-p build serve" //同时执行build和serve
}
- 启动项目: yarn serve
- 安装 yarn add npm-run-all --dev
3、常用的自动化构建工具
- Grunt: 插件生态非常完善,但是由于构建过程是基于临时文件实现的,所欲构建速度较慢;比如使用SACSS文件的构建,先做编译操作,再添加自由属性的前缀,最后压缩代码;在这过程中,grunt每一步都有磁盘读写操作,比如:编译完后,把结果写入临时文件,然后在一个插件再去读取临时文件进行下一步,这样一来,你处理的环节越多,你处理的次数就越多;对超大项目中,项目文件越多,构建速度就会越慢
- Gulp:常用的构建工具,很好的解决了grunt构建速度慢的问题,因为它是基于内存实现的,也就说,对于处理文件的环节都是在内存当中完成的,相对于磁盘读写速度自然就快了很多;
默认支持同时执行多个任务,效率自然就高了,使用方式更加直观易懂,最流的前端构建系统; - FIS:百度前端推介出来的;FIS就像捆绑套餐,把项目当中典型的需求继承于内部,比如: 处理资源加载、模块化开发、性能优化
初学者适合FIS,要求灵活多变适合gulp、grunt 注意: webpack:严格来说,是打包工具
4、grunt的基本使用
- 安装grunt : yarn add grunt
- 项目根目录下添加: gruntfile.js文件
//grunt 入口文件
// 用于定一些需要果grunt自动执行的任务
// 需要导出一个函数
// 此函数接收一个grunt形参,内部提供一些出创建任务时可以用到的API
moudle.exports = grunt=> {
grunt.registerTask('foo', () => {
})
grunt.registerTask('bar','任务描述', () => {
})
// 执行默认任务
grunt.registerTask(‘default’,['foo','bad','far'])
}
5、grunt的标记任务失败
- 构建任务的逻辑发生错误,可以标记任务;
- 使用return false标记任务
- 异步任务无法使用return false返回,指定一个实参
moudle.exports = grunt=> {
grunt.registerTask('bad', () => {
return false
})
}
强制执行任务: yarn grunt default -- force
5、grunt的配置选项API:initConfig
moudle.exports = grunt=> {
grunt.initConfig({
foo: 'bar',
far: {
bar: 123
}
})
grunt.registerTask('foo', () => {
console.log(grunt.config('foo'))
console.log(grunt.config('far.bar'))
})
}
6、grunt的 多目标任务(子任务)
- 使用 registerMultiTask 定义
grunt.initConfig({
build: {
css: '1'
js: '2'
}
})
moudle.exports = grunt=> {
// 多目标配置
grunt.registerMultiTask('build', function() {
console.log('build task')
})
}
7、grunt的 插件使用
- 使用 loadNpmTasks
8、gulp 的使用
核心特点: 高效、易用
- 创建项目的空文件夹
- 初始化package.json yarn init --yes
- 安装 gulp:yarn add gulp --dev
- 查看node-modules/bin/gulp
- 新建一个gulpfile.js
exports.foo = done => {
console.log('foo task working')
done() // 标识任务完成
}