[TOC]
前端工程化
为什么要工程化?
降低开发周期:在不借助开发工具情况下,开发人员要自己编写所有的开发环境等,非常麻烦
规范化,方便开发人员之间的交流
便于日后维护与更新
工程
工程的生命周期
立项 ▶ 需求分析 ▶ 产品原型 ▶ 开发实施 ▶ 测试部署 ▶ 上线运行
工程化
工程化意思是在开发阶段(或者说在做项目过程中)使用各类工具和技术
现在,工程的各个生命周期都有对应的开发工具和技术
通过工具来提升开发效率
发展
前端化主要作用
- 打包代码(压缩代码)
- 解决兼容性问题(如ES6+或CSS3的特性)
- 将Less、Sess等预编译语言转换成普通CSS
- 格式化代码
兼容性查询网站:www.caniuse.com/
适合于 es5 、 css 等
前端工程化包含的内容
| 类型 | 例子 |
|---|---|
| 专业脚手架工具 | vue-cli、create-react-app、angular-cli、gatsbt-cli |
| 通用脚手架工具 | Yeoman、Plop |
| 自动化构建 | npm scripts & script hooks Grunt、Gulp、FIS |
| 模块化打包 | Wevbpack、Rollup、Parcel |
| 标准化规范 | ESLint、StyleLint、Prettier |
| 自动化测试 | Mocha、Jest、Enzyme、Cypress、Nightmare、Puppeteer |
| 自动化部署 | Git Hook、Lint-staged、CI / CD |
浏览器
浏览器就是JavaScript的一个运行环境
浏览器结构
分为外壳和内核两大部分
外壳相当于界面
内核
内核分为两大块:渲染引擎、JS引擎
渲染引擎 用于 渲染 HTML、CSS
JS引擎 用于 加载执行JavaScript
主流浏览器内核引擎
| 浏览器 | 渲染引擎 | js引擎 |
|---|---|---|
| IE、Edge | Trident→EdgeHtml | Chakra |
| Chrome | Webkit→Blink | V8 |
| Safari | Webkit | SquirrelFish |
| Firefox | Gecko | SpiderMonkey |
| Opera | Presto | Carakan |
Node.js
官网: www.nodejs.org
安装:官网下载对应的安装包, 一路 next 安装
版本:
偶数版本为稳定版 (0.6.x ,0.8.x ,0.10.x) 奇数版本为非稳定版(0.7.x ,0.9.x ,0.11.x) LTS(Long Term Support)长期维护版本
运行环境:chrome的V8引擎
(或者说是nodejs是JavaScript的运行环境)
补充:nodejs是除了浏览器外其他能运行JavaScript的工具
nodejs作用
提供环境
分工
JavaScript功能强大,为了方便使用,一般将负责前端的功能交给浏览器;负责后端的功能交给nodejs
前端大致功能有:响应事件(如点击、鼠标进出等)、数据验证、DOM等(注意:无法进行文件操作)
使用nodejs开发后:
- 能更方便使用前端话工具
- 可以在服务端的应用层(BFF)运行,能为网页、APP、小程序等提供数据服务
- 可以用于桌面应用开发
APIs
在浏览器端时,JavaScript分为:ECMAScript、DOM、BOM三部分
其中DOM和BOM属于Web APIs
在使用nodejs时,不会使用 Web APIs、会使用自己的APIs
检测Nodejs版本号
node -v
版本:
偶数版本为稳定版 (0.6.x ,0.8.x ,0.10.x) 奇数版本为非稳定版(0.7.x ,0.9.x ,0.11.x) LTS(Long Term Support)长期维护版本
基础使用
nodejs使用方式有两种:脚本模式、交互模式(REPL)
全局变量
在浏览器端,全局对象为window
在nodejs中,全局对象为global
var a = 1;
console.log(global.a);
注意:在交互模式下,可以按照上述方式访问(global.a)
而在脚本模式下,无法通过上述方式访问(blobal.a)
全局函数
之前学的内置对象的函数方法都可以正常使用(nodejs自带ES5、ES6+)
定时器( setTimeout / clearTimeout )、延时器( setInterval / clearInterval )也可以实现
(注意:定时器、延时器都是window全局对象的方法,这说明global内部也有这两个方法)
新: 全局方法
立即执行的定时器( setImmediate / clearImmediate )
执行顺序:进程 》 立即执行定时器 》 其他定时器
模块(包)
模块是js中封装好功能的对象,大致分为三部分:内置模块、自定义模块、第三方模块
-
内置模块:nodejs自带的,可以直接使用的
-
自定义模块:程序员自己写的,具有一定功能的代码块。
- 文件模块:单独的一个 JS 文件组成的模块
- 目录模块:多个 JS 文件组合在一起,放在一个目录中形成的模块
-
第三方模块:既不是内置模块,也不是自定义模块。
- 对应 Web 端 JS 的第三方库,例如:jQuery,Bootstrap 等。
- 想要使用,必须先安装( 如同使用 jQuery 之前,必须先通过 script 标签引入一样 )
- 在Node.js中,大量的第三方模块通过 npm 来管理。
模块使用
内置模块
console
console 模块提供了一个简单的调试控制台,类似于 Web 浏览器提供的 JavaScript 控制台。
// 数据类型不同,输出后颜色不同
console.log('1');
console.log(1);
// table方法=> 以表格形式展示数据
var obj = { name: 'Tom', age: 19 }
console.log(obj)
console.table(obj) // 以表格方式展示数据
// time方法和timeEnd方法 => 用于记录 两方法之间 程序运行时间
console.time('for');//开始计时
for (var i = 1; i <= 100000; i++) {
}
console.timeEnd('for');//结束计时
console.time('while');
var i = 1;
while (i <= 100000) {
i++;
}
console.timeEnd('while');
process
process 对象是一个全局变量,提供了有关当前 Node.js 进程的信息并对其进行控制。 作为全局变量,它始终可供 Node.js 应用程序使用,无需使用 require()。 它也可以使用 require() 显式地访问:
// process 是全局变量,可以不写 require 引入
const process = require('process');
// 获取操作系统架构 x64
console.log(process.arch)
// 当前系统平台信息 win32
console.log(process.platform)
// 获取当前文件所在的目录 D:\cliu\Desktop\node
console.log(process.cwd())
// 环境变量
console.log(process.env)
// 自定义环境变量
process.env.NODE_ENV = 'develop'
console.log(process.env)
// 获取进程的编号
console.log(process.pid)
// 杀死进程 process.kill(进程编号)
path
path 模块负责文件路径的
- ./ 表示当前目录
- ../ 表示上一级目录
- __dirname 返回当前文件所在的目录
- __filename 返回当前文件的完整路径(目录+文件)
const path = require('path')
// __dirname 获取当前文件所在的目录
path.join(__dirname, 'dist')
console.log('join用于拼接多个路径部分,并转化为正常格式');
const temp = path.join(__dirname, '..', 'lyrics', './友谊之光.lrc');
console.log(temp);
console.log('获取路径中的文件名');
console.log(path.basename(temp));
console.log('获取一个路径中的目录部分');
console.log(path.dirname(temp));
console.log('获取一个路径中最后的扩展名');
console.log(path.extname(temp));
fs
fs (file system)模块主要负责文件基本操作
-
文件操作
// 使用 fs 之前先引入 const fs = require('fs') // 写文件 (清空写入:写入之前会先将文件清空) // fs.writeFile('文件路径','写入内容',回调函数) fs.writeFile('./1.txt', '曾经有一首歌,她感动了我', (err) => { if (err) throw err console.log('写入成功') }) // 读文件 // fs.readFile('文件路径', 回调函数) fs.readFile('./1.txt', (err, data) => { if (err) throw err // data 是二进制数据,默认输出时,以十六进制的方式展示 // 想要看到正常的效果,需要通过 toString() 转换 console.log(data.toString()) }) // 删除文件 # fs.unlink('文件路径', 回调函数) fs.unlink(__dirname+'/1.txt', (err) => { if (err) throw err console.log('删除成功') }) // 追加写入(多次执行,文件中会有多条数据) // fs.appendFile('文件路径','写入内容',回调函数) fs.appendFile(__dirname+'/2.txt', '曾经有一首歌,她是这样唱的\n', (err) => { if (err) throw err console.log('追加写入成功') }) -
目录操作
// 创建目录 => fs的mkdir方法
fs.mkdir("./test1",(err)=>{
if (err) throw err;
console.log("创建成功");
})
// 删除目录 => fs的rmdir方法
fs.rmdir("./test1",(err)={
if (err) throw err;
console.log("删除成功");
})
// 重命名目录 => fs的rename方法
// rename(旧名, 新名, 回调函数)
fs.rename("./test","./test1",function(err){
if (err) console.log(err);
})
// 读取目录 => fs的readdir方法
fs.readdir(__dirname, (err, data) => {
if (err) throw err
// console.log(data) // data 是数组
data.map((d) => {
console.log(d)
})
})
// 判断文件/目录是否存在 => fs的existsSync方法
// true 存在; false 不存在
if (!fs.existsSync('./d2')) {
fs.mkdirSync('./d2')
}
- 查看状态
// 查看文件信息
fs.stat("./test", (err, stat) => {
if (err) throw err
if (stat.isDirectory()) {
// 判断当前文件是否是目录
console.log('目录:', d)
} else if (stat.isFile()) {
// 判断当前文件是否是普通文件
console.log('文件:', d)
}
})
http
以前,我们使用 Apache 或 Nginx 来搭建服务器。Node.js 中,也有搭建服务器的模块。就是 http 模块。
const http = require('http')
// 1. 创建服务器
/**
* req = request 请求
* res = response 响应
*/
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('你好:Node.js')
})
// 2. 发布 web 服务
const port = 3000
const host = 'localhost'
// 在浏览器中访问 http://localhost:3000 然后能看到效果
server.listen(port, host, () => {
console.log(`服务器运行在 http://${host}:${port}`)
})
自定义模块
自定义模块就是开发者自己写的一段代码。可以是一个单独的 JS 文件,也可以是一个目录。
在模块中,只有导出(exports)的属性或方法才能被外部使用,没有导出的属性或方法是模块的私有方法,只能在模块内部使用。
模块的声明:
// circle.js 我们声明一个模块 circle,模块中有两个方法,分别求圆的面积和周长。
const PI = 3.14
// 圆的周长
const perimeter = (r) => {
return 2 * PI * r
}
// 圆的面积
function area (r) {
return PI * Math.pow(r, 2)
}
// 模块内容导出后,才能被外部调用
module.exports = {
perimeter,
area
}
模块的使用:
// 在 app.js 中引入模块
// 引入模块时,需要写引入路径,否则 require('circle') 会报错
const circle = require('./circle')
// 调用模块中的属性或方法
const r = 10
const p = circle.perimeter(r)
const a = circle.area(r)
console.log(`直径为 ${r} 的圆的周长是:` + p)
console.log(`直径为 ${r} 的圆的面积是:` + a)
注意:引入自定义模块时,需要带有引入路径,否则,会报错
路径引入方式
(这里指引入自定义模块时,目录路径引入方式)
- 优先寻找 package.json 的 main 属性
- 找不到前者的基础上,默认 index.js
- 都找不到会报错
第三方模块
第三方模块一般通过 npm (node包管理)来安装使用的
npm官网:www.npmjs.com/
npm 可以帮我们下载(安装)包和包的依赖
- 包:就是一坨代码,就是 Node.js 的第三方模块
- 包的依赖:是指包的辅助代码(例如:下载 Bootstrap 时,必须先下载 jQuery,因为 Bootstrap 是基于 jQuery 开发的,没有 jQuery,Bootstrap 就运行不起来。此时,我们说:Bootstrap 依赖 jQuery )
镜像源
npm 命令下载包的资源地址,成为 npm 的镜像源。
默认 npm 的镜像源是国外的(npmjs.com),下载速度慢,为了提高下载速度,可以将 npm 的镜像源设置为国内的地址(例如:淘宝镜像源)
设置命令为:
# 修改npm的镜像源
npm config set registry https://registry.npm.taobao.org
# 验证是否更改成功(查看镜像源):
npm config get registry
cnpm
为了防止镜像源与原本源冲突,一般将国内提供的镜像源命名为cnpm
安装/使用
npm i cnpm -g
或者
npm install cnpm -g --registry=https://registry.npm.taobao.org
全局与局部
全局安装
全局安装是指把包当作全局命令使用,换句话说就是一次安装,全程使用
安装方式:
npm install <package-name> --global
# 或者
npm i <package-name> -g
使用步骤
- 明确你需求(功能)
- 找到合适的包(npm官网)
- 通过npm指令安装目标包
- 学习如何使用包
局部安装
局部安装就是指包只能在当前项目中使用,不能在项目外使用
安装方式
npm install <package-name>
# 或者
npm i <package-name>
使用步骤
- 创建项目目录(mkdir
project-name) - 进入项目目录(cd
project-name) - 初始化项目(npm init)
- 在项目中安装包
--save与--save-dev
| 全写 | 简写 | 说明 | 例子 |
|---|---|---|---|
| --sava | -S | 开发和上线时安装的包 | jQuery |
| --save-dev | -D | 安装开发环境的包 | minify |
如果在package.json里面观察可以知道
--save对应的是 "dependencies" 属性
--save-dev对应的是 "devDependencies" 属性
脚手架
作用:创建项目基础结构、提供项目规范和约定
分类
一般分为两大类:通用脚手架、专用脚手架
通用脚手架:yeoman
专用脚手架:三大框架的脚手架,create-react-app、vue-cli、angular-cli
通用脚手架:yeoman
功能:脚手架,可以帮助开发人员创建项目基本骨架
yo
说明:yo是Yeoman命令行管理工具,可以在命令行运行Yeoman命令
全局安装
npm i -g yo
# 建议科学上网、或者说使用cnpm
生成器
争对不同需求不同项目而生成的不同脚手架
生成器访问地址:yeoman.io
如果网站被墙,在官网不能查看生成器
解决方案:
- 科学上网
- 通过其他网站:github.com/justjavac/R…
例子
创建一个可运行的项目
# 第一步:创建项目目录(或者说命名项目)
# test为路径名(或者说是项目名)
mkdir test
# 第二步:进入路径(或者说是进入项目中)
cd .\test
# 第三步:初始化项目
yo webapp
## 如果嫌外网慢,可以使用国内镜像源cnpm
## ctrl + C 两遍取消当前加载内容
## 在输入 cnpm i 通过国内资源下载
# 第四步:运行项目
npm run serve
自动化
自动化构建
解释:将手动构建任务,通过命令自动执行的过程
例子: less 转换成 css
npm scripts
作用:在 package.json 中写入"scripts" 属性名,并在内部写入自己命名的属性以及属性值(或者说是命令:任务)
其中属性值就是 控制台指令,这样可以通过
$npm run 属性名
的方式快速运行对应的控制台指令
通配符
npm 脚本就是 Shell 脚本,因为可以使用 Shell 通配符
"style": "lessc *.less"
"style": "lessc **/*.less"
并行执行 parallel
单&符号
任务1 & 任务2
{
...
"scripts":{
"test":"node test1.js & node test2.js"
}
...
}
任务之间没有先后顺序,同时执行可以提高执行效率
(虽然说是一起执行,但相当于开了两个控制端口一起输入命令,而且一般都是按顺序输入,故输入时有先后顺序,会有点影响执行先后顺序)
串行执行 series
双&&符号
任务1 && 任务2
{
...
"scripts":{
"test":"node test1.js && node test2.js"
}
...
}
任务之间有先后顺序,先执行前一个任务,后执行下一个
npm-run-all 插件
安装指令
$npm i npm-run-all
**使用方法 **
- 并行执行
{
"scripts":{
"命令1":"node test1.js",
"命令2":"node test2.js",
"命令名字":"npm-run-all -p 命令1 命令2"
/* 或者简写
"命令名字":"run-p 命令1 命令2"
*/
}
}
- 串行执行
{
"scripts":{
"命令1":"node test1.js",
"命令2":"node test2.js",
"命令名字":"npm-run-all -s 命令1 命令2"
/* 或者简写
"命令名字":"run-s 命令1 命令2"
*/
}
}
- 例子:将 test.less 转换并压缩成 test.min.css
{
"scripts":{
"style":"lessc ./style/test.less ./style/test.css && minify ./style/test.css > ./style/test.min.css"
}
}
ES5兼容方法(Babel)
为了兼容性问题,一般都会把ES6+按顺序转换成ES5
转换规则:
- 识别该语法属于ES6+的哪一代
- 按照下列方式依次转换
ES2018 => ES2017 => ES2016 => ES6 => ES5(最终目标)
使用步骤:
- 配置环境
# 注意:可以配置全局环境(-g),也可以配置局部环境(-D),这里以局部环境为例
# babel-cli 安装babel脚手架
npm i -D babel-cli
# babel-core 安装babel细节
npm i -D babel-core
# babel-preset-env 安装转码规则
npm i -D babel-preset-env
- 编写转码规则
- 新建一个
.babelrc文件(注意:文件只能这样命名,不然无法识别!) - 编写内容(转码规则,“env”为转换成ES5)
- 新建一个
{
"presets":[
"env"
]
}
- 运行
| 功能 | 代码 | 简写 | 细节 |
|---|---|---|---|
| 单个文件转换 | babel input.js --out-file output.js | babel input.js -o output.js | -o |
| 整个目录转换 | babel src --out-dir dist | babel src -d dist | -d |
代码校验
javascript的校验(eslint)
- 安装(配置环境)
# 可以配置全局(-g)、也可以局部(-D),但是建议全局环境
npm i -g eslint
- 初始化配置
# 全局可以直接这么使用
eslint --init
# 局部只能这样使用
./node_modules/.bin/eslint --init
# 区别:
# 局部环境要找到依赖位置过后才能执行
- 配置
创建完成后,在文件目录下可以看见配置文件
设置配置文件中"rules"属性:
| 属性名 | 说明 | 属性值 | 例子 |
|---|---|---|---|
| indent | 缩进 规范 | [type , Num] type:设置缩进冲突时处理方案 如 "off" => 不提醒 "warn"=>警告 "error"=>错误 Num:缩进位数 | "index":["warn",2] |
| quotes | 引号 规范 | [type , method] type:设置缩进冲突时处理方案 如 "off" => 不提醒 "warn"=>警告 "error"=>错误 method:设置单引号或双引号 单引号:single 双引号:double | "quotes":["warn","double] |
- 检查代码格式(运行)
# 单一文件
eslint path/filename.js
# 整个目录
eslint path/dirname
# 在不报编译错误后,可以通过指令来规范化代码
eslint path/dirname --fix
css的校验(stylelint)
- 安装(配置环境)
# 可以全局(-g)也可以局部(-D),但建议安装全局环境
# 安装Stylelint
npm i -g stylelint
# 安装检测标准
npm i -g stylelint-config-standard
- 创建配置文件
.stylelintrc.json
| 属性名 | 说明 | 属性值 |
|---|---|---|
| extends | 代码标准 | stylelint-config-standard |
| rules | 自定义规则 | 对象 |
| "block-no-empty" | rules内部的 代码块为空是否报错 | true:报错 false:忽略 |
注意: 1. rules优先级高于extends
2. 自定义规则可以在stylelint官网查看
- 检测(运行)
# 单个文件
stylelint path/yourfile.js
# 整个目录
stylelint path/dir
Gulp
自动化构建工具——Gulp
常见的三个自动化工具为:Grunt 、 Gulp 、 FIS
自动化工具特点:整理项目文件
优势:
- 使用的是JavaScript语法,方便上手(npm scripts 用的是shell脚本)
- 生态环境好,插件接口多
官网:gulpjs.com/ 可以用官网搜索插件
使用流程
Gulp使用
- 安装Gulp
# 全局配置 gulp脚手架
npm i -g gulp-cli
# 项目初始化后,搭建gulp环境
npm i -D gulp
-
配置任务(指令)文件
- 新建
gulpfile.js文件(文件名不可改) - 编写任务/指令
- 新建
-
执行gulp任务(指令)
安装
# 全局配置 gulp脚手架
npm i -g gulp-cli
# 查看gulp版本
gulp -v
在项目中搭建gulp环境
npm i -D gulp
简单任务(指令)编写
- 简单写个函数,就当成一个简单的任务
const test1 = (cb)={
// 在新版本中,输入参数必须有回调函数cb(其他命名也行如callback)
console.log("test1 is running. ");
cb()
}
// 旧版声明方式
const gulp = require("gulp")
gulp.task("task",(cb)=>{
// task为任务名,cb依旧是回调函数
console.log("old_task is running");
cb();
// 备注:旧版中不需要导出/暴露
})
- 能执行的部分必须导出/暴露
module.export = {
test1,
// default为默认执行部分
default:test1
// 旧版自带导出,不能写,写了会报错
}
这里用之前写好的 gulpfile.js 作为示例
const task1 = (callback)=>{
console.log("task1 is running");
callback();
}
const task2 = (callback)=>{
console.log("task2 is running");
callback();
}
const task3 = (callback)=>{
console.log("default:task3 is running");
callback();
}
module.exports = {
task1,
task2,
default:task3
}
- 控制端口执行
如何编写高级指令将在后面详写
任务(指令)执行方式
开始配置之前,我们先来通过 npm scripts 来复习一下串行并行
Gulp 执行方式 也是 串行执行 和 并行执行
并行执行:gulp.parallel( task1 , task2 , task3 )
串行执行:gulp.series( task1, task2 , task3 )
注意:旧版不支持这样书写
书写方式:
const gulp = require("gulp");
const pp = gulp.parallel(task1,task2,task3);
const ss = gulp.series(task1,task2,task3);
// 之后再导出/暴露
当然,Gulp还支持一些骚操作
gulp.series( task1 , gulp.parallel( task2 , task3 ,gulp.series( task4 , task5 ) ) , task6 )
文件操作
Gulp 是基于 流 的构建系统
通俗说,流就是通过小文件进行传输(就像水滴一样细小能流动)
复制粘贴
文件操作时,分为三部分:输 入、加 工、输 出
分别对应文件流的三部分:读取流、转换流、写入流
例子:*.js 压缩成 *.min.js
| 读取流 | 转换流 | 写入流 |
|---|---|---|
| 读取*.js文件 | 去除空格 | 保存在*.min.js文件中 |
在Gulp中,文件流对应三个函数:src() 、 pipe() 、dest()
| 读取流 | 转换流 | 写入流 |
|---|---|---|
| src() | pipe() | dest() |
// 写法一:
// 导入gulp
const gulp = require("gulp");
// 将css文件内的main.css 复制到 dist文件中(main.css自行创建)
const fileTask = ()=>{
return gulp.src("./css/main.css").pipe(gulp.dest("./dist"));
// 有return ,无需回调
}
// 写法二:
// 解构 方式导入所需函数/方法
const {src,dest} = require("gulp");
const style = () => {
return src('.css/a/main.less', { base: 'css' }).pipe(dest('dist'))
}
src的{base: " 路径 "}属性作用:从"路径"后开始,将下一级目录一并输入在gulp的读取流中
构建样式文件
原理
css文件转换
| 插件名 | 作用 |
|---|---|
| gulp-less | 将less文件转化成css |
| gulp-clean-css | 压缩css文件 |
| gulp-autoprefixer | 将css自动配置兼容属性 |
| gulp-rename | 重命名文件 只改变文件名:直接输入字符串参数 只改变尾缀:输入对象{ "extname": "尾缀" } |
使用方式:
- 配置局部环境
# <name>为上面的插件名
npm i -D <name>
- 导入
const less = require("gulp-less");
const cleancss = require("gulp-clean-css");
const rename = require("gulp-rename");
- 配置
const lessc_min = ()=>{
return gulp.src("./css/main.less")
.pipe(less()).pipe(cleancss())
.pipe(rename({ "extname": ".min.css"}))
.pipe(gulp.dest("./dist"));
};
- 运行
# 这里省略了导出,自行补上
gulp lessc
不同浏览器写法不一样(css hack)
同一段 CSS 代码,在不同浏览器上的呈现效果不同
针对不同的浏览器写相应的 CSS 代码的过程,叫做 CSS hack
这个时候就需要:gulp-autoprefixer插件来兼容
使用方法:
- 配置环境
- 导入
- 配置在文件流的转换流内(gulp.pipe()中)
- 随着命令运行
脚本文件(JS)
| 插件名 | 说明 |
|---|---|
| gulp-babel | 将ES6+语法转换成ES5 注意:使用时要配置好一下插件 babel-core、babel-preset-env |
| gulp-uglify | 压缩js代码 |
| gulp-rename | 修改文件名 |
使用方法:
- 安装运行环境
# <name>
npm i -D <name>
- 导入
const babel = require("gulp-babel");
const uglify = require("gulp-uglify");
const rename = require("gulp-rename");
- 配置
const script = () => {
return src('src/js/main.js')
.pipe(babel({
presets: ['babel-preset-env']
}))
.pipe(uglify())
.pipe(rename({ "extname": ".min.js" }))
.pipe(dest('dist/scripts'));
}
注意:
gulp-babel插件使用时要配置规则,配置方式为传入对象
gulp-babel({persets:[ "babel-persets-env" ]})
若出错,则用 @babel/perset-env 插件
gulp-babel({persets:[ "@babel/persets-env" ]})
html文件压缩
插件名: gulp-htmlmin
使用方法:
- 安装运行环境
npm i -D gulp-htmlmin
- 导入
const htmlmin = require("gulp-htmlmin");
- 配置
const html = () => {
return src('src/index.html')
.pipe(htmlmin({
// 配置压缩语法
collapseWhitespace:true, // 去除标签间的空白
minifyJS: true, // 压缩页面JS
minifyCSS: true // 压缩页面CSS
}))
.pipe(rename({ "extname": ".min.html" }))
.pipe(dest('dist'));
}
图片压缩
插件名: gulp-htmlmin
使用方法:
- 安装运行环境
npm i -D gulp-imagemin
- 导入
const imagemin = require("gulp-imagemin");
- 配置
const html = () => {
return src('src/images/01.png')
.pipe(htmlmin())
.pipe(dest('dist/images'));
}
注意:安装依赖时若是报错(如下)
报错处理:
gulp-imagemin: Couldn't load default plugin "gifsicle"
gulp-imagemin: Couldn't load default plugin "optipng"
解决:
配置 hosts
C:\Windows\System32\Drivers\etc
复制下列代码
# GitHub Start (chinaz.com) =================================================
13.229.188.59 github.com
54.169.195.247 api.github.com
140.82.113.25 live.github.com
8.7.198.45 gist.github.com
# 185.199.108.154 github.githubassets.com
# 185.199.109.154 github.githubassets.com
185.199.110.154 github.githubassets.com
# 185.199.111.154 github.githubassets.com
34.196.247.240 collector.githubapp.com
# 52.7.232.208 collector.githubapp.com
52.216.92.163 github-cloud.s3.amazonaws.com
199.232.96.133 raw.githubusercontent.com
151.101.108.133 user-images.githubusercontent.com
151.101.108.133 avatars.githubusercontent.com
151.101.108.133 avatars0.githubusercontent.com
151.101.108.133 avatars1.githubusercontent.com
151.101.108.133 avatars2.githubusercontent.com
151.101.108.133 avatars3.githubusercontent.com
151.101.108.133 avatars4.githubusercontent.com
151.101.108.133 avatars5.githubusercontent.com
151.101.108.133 avatars6.githubusercontent.com
151.101.108.133 avatars7.githubusercontent.com
151.101.108.133 avatars8.githubusercontent.com
151.101.108.133 avatars9.githubusercontent.com
151.101.108.133 avatars10.githubusercontent.com
151.101.108.133 avatars11.githubusercontent.com
151.101.108.133 avatars12.githubusercontent.com
151.101.108.133 avatars13.githubusercontent.com
151.101.108.133 avatars14.githubusercontent.com
151.101.108.133 avatars15.githubusercontent.com
151.101.108.133 avatars16.githubusercontent.com
151.101.108.133 avatars17.githubusercontent.com
151.101.108.133 avatars18.githubusercontent.com
151.101.108.133 avatars19.githubusercontent.com
151.101.108.133 avatars20.githubusercontent.com
# GitHub End ===================================================================
文件清除
插件名: del
使用方法:
- 安装运行环境
npm i -D del
- 导入
const del = require("del");
- 配置
const html = () => {
return del(["./dist","路径","文件"]);
}
综合操作
// 导入要用的插件,这里略写
const style = ()=>{
// css样式转化,这里略写
}
const script = ()=>{
// javascript代码转化,这里略写
}
const html => ()=>{
// html文件压缩,这里略写
}
const images = ()=>{
// 图片压缩,这里略写
}
const deldist = ()=>{
// 删除dist文件,保证旧文件不会影响新文件
}
// 全部打包(删除原文件,转换新文件)
const build = gulp.series( deldist, gulp.parallel(style,script,html,images) )
开发服务器
前面都是关于文件操作,但只能在本地打开,为了让别人看得到,则需要服务器
插件名: gulp-htmlmin
使用方法:
- 安装运行环境
npm i -D browser-sync
- 导入
const browserSync = require("browser-sync");
- 创建服务器
// 建议直接在导入下面创建
const bs = browserSync.create()
- 启动服务器,并实时监听文件
const serve = () => {
// 监听项目文件,方法来自于 gulp ,可以解构导入
gulp.watch("./project/*.html",html/*html为之前写的压缩代码的方法*/); // 不解构
watch("./project/css/*.less",less); // 解构
watch("./project/js/*.js",js);
// 初始化服务器
bs.init({
// 禁用 浏览器 右上角的 browserSync connected 提示框
notify: false,
// 监听 dist 下文件的变化,然后在浏览器上实时更新
files: 'dist/**',
server: {
// 指定服务启动的目录
baseDir: './dist',
routes: {
'/node_modules': 'node_modules'
}
}
})
}
其他包
bootstrap
注意:bootstrap使用时需要jQuery
使用方式:
- 安装(这里是要用到的,不是配置环境)
npm i -S bootstrap jquery
# 若是使用特定版本 则需要加@声明版本号
npm install --save bootstrap@3.4.1
- 官网中找到合适的样式,复制代码
- 直接在html文件粘贴代码,并将部分路径修改为项目路径
服务器与gulp关系
这里以 yeoman 为例
运行服务器