前端工程化
主要解决的问题
- 传统语言或语法的弊端
- 无法使用模块化/组件化
- 重复的机械式工作
- 代码风格统一、质量保证
- 依赖后端服务接口支持
- 整体依赖后端项目
一切重复的工作都应该被自动化,工程化并不等于工具
创建项目
- 创建项目结构
- 创建特定类型文件
编码
- 格式化代码
- 校验代码风格
- 编译/构建/打包
预览/测试
- Web Server/Mock
- Live Reloading/HMR
- Source Map
提交
- Git Hooks
- Lint-staged
- 持续集成
部署
- CI/CD
- 自动发布
脚手架工具
本质作用
创建项目基础结构、提供项目规范和约定
常用的脚手架工具
- React ->create-react-app
- Vue ->vue-cli
- Angular ->angular-cli
- Yeoman
- Plop
Yeoman
脚手架的运行平台,可以创建任何项目;过于通用不够专注
基础使用
基于node.js开发的工具模块
安装 yarn global add yo
安装generator yarn global add generator-node
generator
基本结构
nvm:node版本控制与切换.
创建:
- mkdir generator-sample
- cd generator-sample\
- yarn init
- yarn add yeoman-generator
plop
小而美的脚手架工具
- 将plop模块做为项目开发依赖安装
- 在项目根目录下创建一个plopfile.js文件
- 在plopfile.js文件中定义脚手架任务
- 编写用于生成特定类型文件的模板
- 通过plop提供的cli运行脚手架任务
脚手架的工作原理
mkdir sample-scaffolding
cd sample-scaffolding
yarn init
在packsge.json添加
“bin”:“cli.js”
自动化构建
npm script
常用的构建工具
Grunt、Gulp、FIS
- Gulp效率比较高,易懂
- FIS适合初学者
grunt
创建一个空项目
- yarn init --yes
- yarn add grunt
- yarn grunt bar
标记任务失败
grunt.registerTask('foo', () => {
console.log("hello grunt~");
return false
})
//异步
grunt.registerTask('async-task', function() {
const done = this.async()
setTimeout(() => {
console.log('bad async');
done(false)
}, 1000);
})
- yarn grunt default --force 跳过失败的继续进行
插件使用
- 安装插件 yarn add grunt-contrib-clean
module.exports=grunt=>{
grunt.initConfig({
clean:{
temp:'temp/app.js'
}
})
//载入
grunt.loadNpmTasks('grunt-contrib-clean')
}
- yarn grunt clean
常用插件
yarn add grunt-sass sass --dev
Gulp
基于流的构建系统
yarn init --yes
yarn add gulp --dev
根目录下创建gulpfile.js gulp的入口文件
yarn gulp 方法名 -----执行
核心工作原理
读取流->转换流->写入流
const fs = require('fs')
const { Transform } = require('stream')
exports.default = () => {
// 文件读取流
const readStream = fs.createReadStream('normalize.css')
// 文件写入流
const writeStream = fs.createWriteStream('normalize.min.css')
// 文件转换流
const transformStream = new Transform({
// 核心转换过程
transform: (chunk, encoding, callback) => {
const input = chunk.toString()
const output = input.replace(/\s+/g, '').replace(/\/\*.+?\*\//g, '')
callback(null, output)
}
})
return readStream
.pipe(transformStream) // 转换
.pipe(writeStream) // 写入
}
文件操作API&插件的使用
//压缩
yarn add gulp-clean-css --dev
//修改文件名
yarn add gulp-rename
const { src, dest } = require('gulp')
const cleanCSS = require('gulp-clean-css')
const rename = require('gulp-rename')
exports.default = () => {
return src('src/*.css')
.pipe(cleanCSS())
.pipe(rename({ extname: '.min.css' }))
.pipe(dest('dist'))
}
封装工作流
在桌面安卓 zce-cli
yarn global add zce-cli
总结
gulp
- 构建
- 任务
- 任务调用
我们可以人为的控制pipe 的书写顺序 - 管道流
一个pipe就是一个功能
我们对应着一个插件
gulp什么都做不了(什么都能做,取决于你能实现什么样的外部插件)
webpack - 打包
我们可以认为gulp 什么事情都做不了,它就是一个任务调度器
当前我们主要从事的是webpack前端,我们大量的使用前端框架,因此我们总是在做打包工作(js css img iconfont)
但是如果说我们当前做的项目不是浏览器平台下的前端项目,这个时候gulp 其实就有用了
一、手写打包器
node.js应用
webpack
二、调试webpack打包