Gulp学习
1.第三方模块
Gulp是基于node平台开发的前端构建工具
将机械化操作编写成任务,想要执行机械化操作时执行一个命令行命令任务就能自动执行
1.1 Gulp能做什么
· 项目上线,HTML、css、js 文件压缩合并
· 语法转换(es6、less...)
· 公共文件抽离
· 修改文件浏览器自动刷新
1.2 Gulp使用
① 使用npm install gulp 下载gulp库文件
② 在项目根目录下建立gulpfile.js 文件
③ 重构项目的文件夹结构src目录放置源代码文件 dist 目录放置构建后文件
④ 在gulpfile.js文件中编写任务
⑤ 在命令行工具中执行gulp任务
1.3 Gulp 中提供的方法
· gulp.src(): 获取任务要处理的文件
· gulp.dest(): 输出文件
· gulp.task(): 建立gulp任务
· gulp.watch(): 监控文件的变化
-g 表示全局安装
安装Gulp 命令行工具
npm install gulp-cli -g
//gulpfile.js //引用gulp模块 const gulp = require('gulp'); //使用gulp.task建立任务 //1.任务的名称 //2.任务的回调函数 gulp.task('first', () =>{ //使用gulp.src获取要处理的文件 gulp.src('./src/css/style.css') .pipe(gulp.dest('dist/css')); });
后运行 gulp first
1.4 Gulp 插件
· gulp-htmlmin : html文件压缩
· gulp-csso : 压缩css
· gulp-babel : JavaScript语法转化
· gulp-less : less语法转化
· gulp-uglify : 压缩混淆JavaScript
· gulp-file-include 公共文件包含
· browsersync 浏览器实时同步
//引用gulp模块 const gulp = require('gulp'); const fileinclude = require('gulp-file-include'); const htmlmin = require('gulp-htmlmin'); const less = require('gulp-less'); const csso = require('gulp-csso'); const babel = require('gulp-babel'); const uglify = require('gulp-uglify'); //使用gulp.task建立任务 //1.任务的名称 //2.任务的回调函数 gulp.task('first', () =>{ //使用gulp.src获取要处理的文件 gulp.src('./src/css/style.css') .pipe(gulp.dest('dist/css')); }); //html任务 //1.html文件中代码的压缩操作 //2.抽取html文件中的公共代码 gulp.task('htmlmin', () => { gulp.src('./src/*.html') .pipe(fileinclude()) //压缩html文件中的代码 .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest('dist')); }); //css任务 //1.less语法转义 //2.css代码压缩 gulp.task('cssmin',() => { //选择css目录下的所有less文件以及css文件 gulp.src(['./src/css/*.less','./src/css/*.css']) //将less语法转换为css语法 .pipe(less()) //将css代码进行压缩 .pipe(csso()) //将处理结果进行输出 .pipe(gulp.dest('dist/css')) }); //js任务 //1.es6代码转换 //2.代码压缩 gulp.task('jsmin',() => { gulp.src('./src/js/*.js') .pipe(babel({ //可以判断当前代码的运行环境 将代码转换为当前运行环境所支持的代码 presets: ['@babel/env'] })) //压缩js代码 .pipe(uglify()) .pipe(gulp.dest('dist/js')) }); //复制文件夹 gulp.task('copy',() => { gulp.src('./src/images/*') .pipe(gulp.dest('dist/images')); gulp.src('./src/lib/*') .pipe(gulp.dest('dist/lib')) }); //构建任务 当任务名称是default的时候 命令行直接输入gulp 回车即可 gulp.task('default',['cssmin','htmlmin','jsmin','copy'])
//构建任务 当任务名称是default的时候 命令行直接输入gulp 回车即可 gulp.task('default',['first','cssmin','htmlmin'])
2. package.json文件
2.1 node_modules文件夹的问题
① 文件夹以及文件过多过碎,当将项目整体拷贝给别人的时候,传输速度会很慢。
② 复杂的模块依赖关系需要被记录,确保模块的版本和当前保持一致,否则会导致当前项目运行报错。
2.2 package.json文件的作用
项目描述文件,记录当前项目信息,例如项目名称、版本、作者、github地址、当前项目依赖了哪些第
三方模块等。
使用 npm init -y 命令生成package.json文件。
package.json
拿到拷贝的项目后
在项目根目录运行命令窗口
运行命令 npm install npm工具会自动到项目根目录找package.json文件 找dependencies选项 下载项目需要的第三方模块 生成项目需要的node_modules 文件夹
2.3 项目依赖
· 在项目的开发阶段和线上运营阶段,都需要依赖的第三方包,称为项目依赖
· 使用npm install 包命令下载的文件会默认被添加到package.json文件的dependencies字段中
2.4 开发依赖
· 在项目的开发阶段需要依赖,线上运营阶段不需要依赖的第三方包,称为开发依赖
· 使用npm install 包名 --save-dev命令将包添加到package.json文件的devDependencies字段中
dependencies:存储的是项目依赖
devDependencies:存储的是开发依赖
npm install 开发环境 下载所有的依赖
npm install --production 只下载项目依赖
2.5 package-lock.json 文件的作用
· 锁定包的版本,确保再次下载时不会因为包版本不同而产生问题
· 加快下载速度,因为该文件中已经记录了项目所依赖第三方包的树状结构和包的下载地址,重新安装
时只需下载即可,不需要做额外的工作
package.json中 scripts保存的命令别名 运行时 只需 npm run 别名名称 即可运行对应的命令
3 Node.js 中模块的加载机制
3.1模块查找规则 - 当模块拥有路径但没有后缀时
① require方法根据模块路径查找模块,如果是完整路径,直接引入模块。
② 如果模块后缀省略,先找同名JS文件再找同名JS文件。
③ 如果找到了同名文件夹,找文件夹中的index.js
④ 如果文件交中没有index.js就会去当前文件交中的package.json文件中查找main选项中的入口文件
⑤ 如果找指定的入口文件不存在或者没有指定入口文件就会报错,模块没有被找到
3.2 模块查找规则 - 当模块没有路径且没有后缀时
① Node.js会假设它是系统模块
② Node.js 会去node_moodules文件夹中
③ 首先看是否有该名字的JS文件
④ 再看是否有该名字的文件夹
⑤ 如果是文件夹看里面是否有index.js
⑥ 如果没有index.js 查看该文件夹中的package.json中的main选项确定模块入口文件
⑦ 否则找不到报错
4.服务器端基础
URL的组成
传输协议://服务器IP或域名:端口(默认80可以不写)/资源所在位置标识
http://www.baidu.com/news/20200830/081533324.html
http: 超文本传输协议,提供了一种发布和接收HTML页面的方法

5.创建web服务器
步骤
① 根目录创建app.js
//app.js //用于创建网站服务器的模块 const http = require('http'); //app对象就是网站服务器对象 const app = http.createServer(); //当客户端有请求来的时候 执行事件处理函数 app.on('request',(req, res) =>{ res.end('<h1>hello user!</h1>') }); app.listen(3000); console.log('网站服务器启动成功');
② 命令窗口运行 node app.js
③ 浏览器输入 localhost:3000
6. HTTP协议
6.1 请求报文
① 请求方式
· GET 请求数据(获取数据)
· POST 发送数据(添加数据)
app.on('request',(req, res) =>{
//获取请求地址
req.url
//获取请求方式
req.method
//获取请求报文
req.headers或 req.headers['accept']
res.end('<h1>hello user!</h1>')
});
6.2 响应报文
(1)HTTP状态码
· 200 请求成功
· 404 请求的资源没有被找到
· 500 服务器端错误
· 400 客户端请求有语法错误
(2)内容类型
· text/html
· text/css
· application/javascript
· image/jpeg
· application/json
//当客户端有请求来的时候 app.on('request',(req, res) =>{ //获取请求地址 //req.url //获取请求方式 //req.method //获取请求报文 //req.headers res.writeHead(200,{ 'content-type':'text/html;charset=utf8' }); res.end('<h1>hello user!</h1>'); });
7. HTTP 请求与响应处理
7.1 请求参数
客户端向服务器端发送请求时,有时需要携带一些客户信息,客户信息需要通过请求参数的形式传递到
服务器端,比如登录操作。
7.2 GET 请求参数(服务器端通过参数名字接收)
· 参数被放置在浏览器地址栏中,例如:http://localhost:3000/?name=zhangsan&age=20naliu555@163.com
//用于创建网站服务器的模块 const http = require('http'); //用于处理url地址 const url = require('url'); //app对象就是网站服务器对象 const app = http.createServer(); //当客户端有请求来的时候 app.on('request',(req, res) =>{ //获取请求地址 //req.url //获取请求方式 //req.method //获取请求报文 //req.headers //parse第一个参数 要解析的URL地址 第2个参数 将查询参数解析成对象形式 let { query, pathname } = url.parse(req.url,true); console.log(query.name); console.log(query.age); if(pathname == '/index' || pathname == '/'){ res.end('<h2>欢迎来到首页</h2>') }else if(pathname == '/list'){ res.end('welcome to listpage'); }else{ res.end('not found'); } res.writeHead(200,{ 'content-type':'text/html' }); res.end('<h1>hello user!</h1>'); }); app.listen(3000); console.log('网站服务器启动成功');
7.3 POST请求参数
· 参数被放置在请求体中进行传输
· 获取POST参数需要使用data事件和end事件
· 使用querystring 系统模块将参数转换为对象格式
//post.js //用于创建网站服务器的模块 const http = require('http'); //app对象就是网站服务器对象 const app = http.createServer(); //处理请求参数模块 const querystring = require('querystring'); //当客户端有请求来的时候 app.on('request',(req, res) =>{ //post 参数是通过事件的方式接收的 //data 当请求参数传递的时候触发data事件 //end 当参数传递完成的时候触发end事件 let postParams = ''; req.on('data', params =>{ postParams += params; }); req.on('end',() =>{ console.log(querystring.parse(postParams)); }); res.end('ok'); }); //监听端口 app.listen(3000); console.log('网站服务器启动成功');
7.4 路由
路由是指客户端请求地址与服务器端程序代码的对应关系。简单的说,就是请求什么响应什么

//1.引入系统模块http //2.创建网站服务器 //3.为网站服务器对象添加请求事件 //4.实现路由功能 // 1)获取客户端的请求方式 // 2)获取客户端的请求地址 const http = require('http'); const app = http.createServer(); const url = require('url'); app.on('request',(req,res) => { //获取请求方式 const method = req.method.toLowerCase(); //获取请求地址 const pathname = url.parse(req.url).pathname; res.writeHead('200',{ 'content-type':'text/html;charset=utf8' }); if(method == 'get'){ if(pathname == '/' || pathname == '/index'){ res.end('欢迎来到首页'); }else if(pathname == '/list'){ res.end('欢迎来到列表页'); }else{ res.end('您输入的网址不存在'); } }else if(method == 'post'){ } }); app.listen(3000); console.log('服务器启动成功');
7.5 静态资源
服务器端不需要处理,可以直接响应给客户端的资源就是静态资源,例如css、JavaScript、image文件 。
npm install mime 安装第三方模块mime
mime模块可以根据当前请求路径 分析出资源的类型 把类型通过返回值的方式返回
const http = require('http');
const app = http.createServer();
const url = require('url');
const path = require('path');
const fs = require('fs');
const mime = require('mime');
app.on('request',(req,res) => {
//获取请求路径
let pathname = url.parse(req.url).pathname;
pathname = pathname == '/'? '/index.asp' : pathname;
let realPath = path.join(__dirname,'public'+ pathname);
let type = mime.getType(realPath);
fs.readFile(realPath,(error, doc) =>{
if(error!=null){
res.writeHead('404',{
'content-type':'text/html;charset=utf8'
});
res.end('文件读取失败');
return;
}
//读取的外链类型(css、js等)
res.writeHead(200,{
'content-type':type
})
res.end(doc);
});
});
app.listen(3000);
console.log('服务器启动成功');
7.6 动态资源
相同的请求地址不同的响应资源,这种资源就是动态资源。
8. Node.js异步编程
8.1 同步API,异步API
同步API: 只有当前API执行完成后,才能继续执行下一个API
console.log('before');
console.log('after');
异步API: 当前API的执行不会阻塞后续代码的执行
console.log('before');
setTimeout(() =>{
console.log('last');
},2000)
console.log('after');
不能通过返回值的方式拿到异步API执行的结果
function getMsg(callback){ setTimeout({ callback({ msg:'Hello shihan'; }) },2000) } //通过传回调函数获取异步API的执行结果 getMsg((data) => { console.log(data); });
8.2 同步API,异步API的区别(获取返回值)
同步API可以从返回值中拿到API执行的结果,但是异步API是不可以的
8.3 回调函数
自己定义函数让别人去调用
8.5 同步API,异步API 的区别(代码执行顺序)
同步API从上到下依次执行,前面代码会阻塞后面代码的执行
异步API不会等API执行完成后再向下执行代码
Node.js 会将所有同步API执行完成后 再执行异步API

8.8 Promise
Promise 出现的目的是解决Node.js异步编程中回调地狱的问题。
const fs = require('fs');
//文件读取回调地狱问题
// fs.readFile('./1.txt','utf8',(err,res1){
// console.log(res1);
// fs.readFile('./2.txt','utf8',(err,res2){
// console.log(res2);
// fs.readFile('./3.txt','utf8',(err,res3){
// console.log(res3);
// })
// })
// })
function p1(){
//返回peomise对象
return new Promise((resolve,reject) =>{
fs.readFile('./1.txt','utf8',(err,result1) =>{
resolve(result1)
})
});
}
function p2(){
return new Promise((resolve,reject) =>{
fs.readFile('./2.txt','utf8',(err,result2) =>{
resolve(result2)
})
});
}
function p3(){
return new Promise((resolve,reject) =>{
fs.readFile('./3.txt','utf8',(err,result3) =>{
resolve(result3)
})
});
}
//promise 提供了链式编程的写法
p1().then((r1) =>{
console.log(r1);
return p2();
})
.then((r2) =>{
console.log(r2);
return p3();
})
.then((r3) => {
console.log(r3);
})
8.9 异步函数
异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,使代码变得清晰明了。
//1. 在普通函数定义的前面加上async关键字,普通函数就变成了异步函数 //2. 异步函数默认的返回值是promise对象 //3. 在异步函数内部使用throw关键字 进行错误的抛出 // //await关键字 //1)只能出现在异步函数中 //2)await 后面跟promise对象 它可以暂停异步函数的执行 等待promise对象返回结果后再向下执行函数 async function fn() { //throw抛出错误 throw执行 后面的代码将不再执行 throw '出现了一些错误'; return 123; } fn().then((data) =>{ console.log(data); }).catch((err) =>{ console.log(err); })
asayc 关键字
1)普通函数定义前加async关键字 普通函数变成异步函数
2)异步函数默认返回promise对象
3)在异步函数内容使用return关键字进行结果返回 结果会被包裹的promise对象中 return关键字代替了resolve方法
4)在异步函数内部使用throw关键字抛出程序异常
5)调用异步函数再链式调用then 方法获取异步函数执行结果
6)调用异步函数再链式调用catch方法获取异步函数执行的错误信息
await 关键字
1)await关键字只能出现在异步函数中
2)await promise await后面只能写promise对象 写其他类型的API是不可以的
3)await关键字可以暂停异步函数向下执行 直到promise返回结果
const fs = require('fs');
// 改造现有异步函数API 让其返回promise对象 从而支持异步函数语法
const promisify = require('util').promisify;
const readFile = promisify(fs.readFile);
async function run(){
let r1 = await readFile('./1.txt','utf8');
let r2 = await readFile('./2.txt','utf8');
let r3 = await readFile('./3.txt','utf8');
console.log(r1);
console.log(r2);
console.log(r3);
}
run();

浙公网安备 33010602011771号