第三方模块-Gulp
解释
基于node平台开发的前端构建工具
将机械化操作编写成任务,由一条命令来触发执行,提高开发效率
主要能做什么
- 项目上线:html、css、js文件的压缩合并
- 语法转换:es6、less等语言的转化
- 公共文件抽离
- 修改文件后浏览器自动刷新
Gulp使用
- 下载框架库:
npm install gulp
- 在根目录下建立gulpfile.js文件中
- 建立项目文件夹目录,如:src,dist等
- 在gulpfile.js中编写任务
- 在命令行工具中执行gulp任务
Gulp中提供的方法
- gulp.src():获取任务要处理的文件
- gulp.dest():输出文件
- gulp.task():建立gulp任务
- gulp.watch():监控文件的变化
具体实例,在自己创建的gulpfile.js中写入:
javascript
//引用模块
const gulp = require("gulp");
//使用gulp.task建立任务
//1.任务的名称
//2.任务的回调
gulp.task('first',()=>{
console.log("这是第一次创建任务");
// gulp.src('./src/122.txt')这个方法获取到文件,经处理输出到gulp.dest('./dist/css.txt')文件下
// pipe有管道的意思,上一个文件获取到后,通过本方法传送到下一个处理方法
gulp.src('./src/122.txt').pipe(gulp.dest('./dist/css.txt'))
})
此时不能直接使用node gulpfile.js命令来执行本文件,因为使用node命令会执行整个js文件,但我们只想执行gulp的task任务。因此我们要使用gulpfile提供的命令行工具来执行命令。
首先安装gulp-cli:
bash
// 因为其他项目可以也会用,所以我们添加 -g 全局安装
npm install gulp-cli -g
安装成功后,在gulpfile.js文件目录中执行cmd命令:
bash
# first是我们刚才创建的任务命
gulp first
这时就运行成功了
Gulp插件
当我们想压缩项目中各种文件时,需要下载和使用gulp中的各种插件
- gulp-htmlmin - html文件压缩
- gulp-csso - 压缩css
- gulp-babel - JavaScript语法转化
- gulp-less - less语法转化
- gulp-uglify - 压缩混淆JavaScript
- gulp-file-include - 公共文件包含
- browsersync - 浏览器实时同步
插件比较多,现在只列举其中一个,将项目中html代码压缩
先下载相关插件:
bash
npm install gulp-htmlmin
使用:
javascript
//引用模块
const htmlmin = require("gulp-htmlmin");
gulp.task("htmlmin",() => {
gulp.src('./src/*.html')
.pipe(htmlmin({collapseWhitespace:true}))
.pipe(gulp.dest('dist'))
})
因为gulp的插件太多了,一个一个演示不现实,如果有不清楚的可以直接查看官网的使用方式:npm | Home (npmjs.com)
抽取公共模块
利用gulp-file-include插件实现
bash
npm install gulp-file-include
先将公共模块抽取出来,然后在需要使用模块的html文件中使用@@include(文件路径)就可以将公共模块重新使用了。
javascript
//引用模块
const htmlmin = require("gulp-htmlmin");
//引用模块
const fileinclude = require("gulp-file-include");
gulp.task("htmlmin",() => {
gulp.src('./src/*.html')
.pipe(fileinclude())
.pipe(htmlmin({collapseWhitespace:true}))
.pipe(gulp.dest('dist'))
})
js中模块的查找规则
一、当模块没有后缀时
javascript
require('./find.js')
require('./find')
- require方法根据模块路径查找模块,如果是完整路径,直接引入模块
- 如果模块后缀省略了,先找同名的js文件在找同名的js文件夹
- 如果找到了同名文件夹,找文件夹中的index.js
- 如果文件夹中没有index.js就去当前文件夹中的package.js文件中查找main选项的入口文件
- 如果找指定的入口文件不存在或者没有指定入口文件就会报错,模块没有找到
二、当模块没有路径和后缀时
javascript
require('find')
- Node.js会假设他是系统模块
- Node.js会去node_modules文件夹中
- 首先看是否有改名字的js文件
- 在看是否有该名字的文件夹
- 如果是文件夹看里面是否有index.js
- 如果没有index.js查看该文件夹中的package.json中的main选项确定模块入口文件
- 否则找不到报错
创建web服务器
创建web服务器
使用http模块创建网站服务器-app.js
javascript
//引入http模块
const http = require("http");
//创建网络服务器
const app = http.createServer();
// 监听一个事件处理函数
// 当客户端有请求信息来是
app.on('request',(req,res)=>{
// req 保存了客户端请求的信息
// res 相应的内容
// 向用户响应一个指定的数据
res.end("<h1>您好,我在呢</h1>")
})
// 设置监听的端口
app.listen(499);
console.log("服务器启动成功");
此时,在目录处打开cmd,输入命令:node app.js
报文
在http请求和响应的过程中传递的数据库就叫做报文,包括要传送的数据和一些附加的信息,并遵守一定的规则
请求方式
GET:请求数据
POST:发送数据
javascript
app.on('request',(req,res)=>{
// 打印客户端请求的方式
console.log(req.method)
// 向用户响应一个指定的数据
res.end("<h1>您好,我在呢</h1>")
})
在浏览器中我们发送数据时一般是post请求,请求数据时为get请求。不过我们可以通过某种方式干扰这些默认请求的方式。
如使用from标签请求、使用ajax请求等
响应
响应码:
- 200:请求成功
- 500:服务器错误
- 404:资源未找到
- 400:前端请求方式错误
内容类型:
- text/html
- text/css
- application/javascript
- image/jpeg
- application/json
javascript
//引入http模块
const http = require("http");
//创建网络服务器
const app = http.createServer();
// 监听一个事件处理函数
app.on('request',(req,res)=>{
// 为响应结果设置状态码
res.writeHead(200,{
"content-type":"text/plain;charset=utf8"
})
// 如果想让此时的h1标签在浏览器中生效,则将返回结果改变为:content-type:text/html即可
res.end("<h1>您好,我在呢</h1>")
})
// 设置监听的端口
app.listen(499);
console.log("服务器启动成功");
获取请求参数
例如请求的地址为:http://127.0.0.1:80/list?id=1
javascript
//引入http模块
const http = require("http");
// 用户处理url地址
const url = require("url")
//创建网络服务器
const app = http.createServer();
// 监听一个事件处理函数
app.on('request',(req,res)=>{
console.log(req.url,'请求的地址') // list?id=1
// url.parse(url地址,flag标识)
// @param flag 将查询参数解析成对象,如果不传将解析成字符串格式,使用不方便
let parseUrl= url.parse(req.url,true)
console.log(parseUrl.query) // {id:1}
if(parseUrl.pathname == "/index"){
res.end("<h1>欢迎来到首页</h1>")
}else{
res.end("<h1>你好啊</h1>")
}
})
// 设置监听的端口
app.listen(499);
console.log("服务器启动成功");
事件-
-
data: 当请求参数传递时触发data事件
-
end: 当参数传递完成时触发end事件
-
querystring: 当解析参数时使用该模块
querystring和url的区别:url是用来处理请求地址的,如:find?id=1,querystring是用来处理参数的,如:id=1。
当使用post请求时需要将参数先取到,然后执行下面的操作
如请求的链接是:http://localhost/find?id=1\&userId=2
javascript
//引入http模块
const http = require("http");
// 处理请求参数模块
const querystring = require("querystring")
//创建网络服务器
const app = http.createServer();
// 监听一个事件处理函数
app.on('request',(req,res)=>{
// data 当请求参数传递时触发data事件
// ennd 当参数传递完成时触发end事件
let params = ''
req.on('data',param=>{
params += param
})
req.on('end',param=>{
console.log(params) // id=1&userId=2
// 注意:url模块是处理请求地址的,但我们现在想处理请求参数,所以要使用querystring模块
console.log(querystring.parse(params)) // {id:1,userId:2}
})
})
// 设置监听的端口
app.listen(499);
console.log("服务器启动成功");
路由
路由是指客户端请求地址与服务器端程序代码的映射关系。
通过输入http://localhost/list.html获取http://localhost/public/list.html下的静态资源
javascript
//引入http模块
const http = require("http");
const url = require('url')
const path = require('path')
const fs = require('fs')
//创建网络服务器
const app = http.createServer();
// 监听一个事件处理函数
app.on('request',(req,res)=>{
let pathname = url.parse(req.url).pathname;
// 得到静态资源的绝对路径
let respath = path.join(__dirname,'public',pathname);
console.log(respath)
// 读取文件内容
fs.readFile(respath,(err,result)=>{
if(err==null){
res.writeHead(404,{
"content-type":"text/html;charset=utf8"
})
res.end("文件不存在")
}else{
res.writeHead(200,{
"content-type":"text/html;charset=utf8"
})
res.end(result)
}
})
})
// 设置监听的端口
app.listen(499);
console.log("服务器启动成功");
需要注意:注意返回文本的格式编码改为utf8。之所以有时候不会乱码,是因为当我们在html页面执行时,页面的头部标签处已经指定好编码格式了,所以我们不需要再服务端指定编码格式。
mime模块
此模块可以根据请求路径将返回类型输出。使用方式如下:
javascript
const mime = require("mime");
const path = require("path")
// 路径地址
let basePath = '/default.html'
// 绝对路径
let realPath = path.join(__dirname,'public',basePath);
// mime相关方法
console.log(mime.getType(realPath)) // text/html
同步API/异步API
同步
代码从上到下依次执行,只有上行代码执行完后才能执行下方代码,如:
参考:Promise
异步
代码的执行不会因为上方代码执行缓慢而影响下方代码的执行,如:
javascript
console.log("before")
setTimeout(()=>{
console.log('time')
},100)
console.log('after')
// 代码运行
before
after
time
全局对象
在浏览器中全局对象是window,在Node中全局对象是global。
在使用中可以向window中一样,将global省略的。