node.js
时钟web服务器案例
先创建好本次案例所需要的文件。
其中index.css代码
html,
body {
margin: 0;
padding: 0;
height: 100%;
background-image: linear-gradient(to bottom right, red, gold);
}
.box {
width: 400px;
height: 250px;
background-color: rgba(255, 255, 255, 0.6);
border-radius: 6px;
position: absolute;
left: 50%;
top: 40%;
transform: translate(-50%, -50%);
box-shadow: 1px 1px 10px #fff;
text-shadow: 0px 1px 30px white;
display: flex;
justify-content: space-around;
align-items: center;
font-size: 70px;
user-select: none;
padding: 0 20px;
/* 盒子投影 */
-webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0%, transparent), to(rgba(250, 250, 250, .2)));
}
index.js代码
window.onload = function () {
// 定时器,每隔 1 秒执行 1 次
setInterval(() => {
var dt = new Date()
var HH = dt.getHours()
var mm = dt.getMinutes()
var ss = dt.getSeconds()
// 为页面上的元素赋值
document.querySelector('#HH').innerHTML = padZero(HH)
document.querySelector('#mm').innerHTML = padZero(mm)
document.querySelector('#ss').innerHTML = padZero(ss)
}, 1000)
}
// 补零函数
function padZero(n) {
return n > 9 ? n : '0' + n
}
index.html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>index首页</title>
<link rel="stylesheet" href="./index.css"/>
</head>
<body>
<div class="box">
<div id="HH">00</div>
<div>:</div>
<div id="mm">00</div>
<div>:</div>
<div id="ss">00</div>
</div>
<script src="./index.js"></script>
</body>
</html>
服务器代码,14.js
// 1.1导入 http模块
const http = require('http')
// 1.2导入fs模块
const fs = require('fs')
// 1.3导入 path模块
const path = require('path')
// 2.1创建web服务器
const server = http.createServer()
// 2.2监听web 服务器的request事件
server.on('request', (req, res) => {
// 3.1获取到客户端请求的URL地址
// /clock/index.html
// /clock/index.css
// /clock/index.js
const url = req.url
// 3.2把请求的URL地址映射为具体文件的存放路径,即当前该js文件所处的目录与url地址进行拼接
const fpath = path.join(__dirname, url)
// 4.1根据“映射”过来的文件路径读取文件的内容
fs.readFile(fpath, 'utf8', (err, dataStr) => {
// 4.2读取失败,向客户端响应固定的“错误消息”
if (err) return res.end('404 Not found.')
// 1.3 读取成功,将读取成功的内容,响应给客户端
res.end(dataStr)
})
})
// 2.3启动服务器
server.listen(80, () => {
console.log('server running at http://127.0.0.1')
})
终端输入node .\14clock时钟web服务器.js
运行。打开生成的链接。发现出现了404 not found,这是因为我们打开链接,默认的访问URL地址是/
,并不是我们代码中所需要的/clock/index.html
。
此时我们手动在浏览器中增加地址,按回车,就会发现,能正常访问了。
那么我们希望可以访问时,在初始的地址上只需添加/
或者/index.html
也能正常访问,就需要对资源的请求路径进行优化了。修改14.js文件如下
// 1.1导入 http模块
const http = require('http')
// 1.2导入fs模块
const fs = require('fs')
// 1.3导入 path模块
const path = require('path')
// 2.1创建web服务器
const server = http.createServer()
// 2.2监听web 服务器的request事件
server.on('request', (req, res) => {
// 3.1获取到客户端请求的URL地址
// /clock/index.html
// /clock/index.css
// /clock/index.js
const url = req.url
// 3.2把请求的URL地址映射为具体文件的存放路径,即当前该js文件所处的目录与url地址进行拼接
// const fpath = path.join(__dirname, url)
//5.1对访问资源的路径进行优化,我们在后台服务器的代码里边,对用户的请求路径做优化
let fpath = ''
// 如果用户访问的URL路径是 /,则代码访问的是index.html,即首页
if (url === '/') {
fpath = path.join(__dirname, './clock/index.html')
} else {
// 如果用户访问的url路径是 /index.html,则访问的也是首页。
// /index.html
// /index.css
// /index.js
fpath = path.join(__dirname, '/clock', url)
}
// 4.1根据“映射”过来的文件路径读取文件的内容
fs.readFile(fpath, 'utf8', (err, dataStr) => {
// 4.2读取失败,向客户端响应固定的“错误消息”
if (err) return res.end('404 Not found.')
// 1.3 读取成功,将读取成功的内容,响应给客户端
res.end(dataStr)
})
})
// 2.3启动服务器
server.listen(80, () => {
console.log('server running at http://127.0.0.1')
})
终端重新运行,查看效果。
模块化
模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说,模块是可组合、分解和更换的单元。
node.js中的模块化
新建两个js文件
其中15.js代码
// 该模块为自定义模块
console.log('已经加载了15自定义模块');
16.js代码
const custom = require('./15自定义模块')
console.log(custom);
运行一下node .\16调用自定义模块.js
结果如下所示:
模块作用域
在01.js中先定义username变量,在02.js中引入01.js文件,然后打印输出发现为空对象{ },即与username有关的代码都没法在02.js中执行,只能在01.js中执行。
比如下图,有res.js和login.js都定义了一个username变量。那么当index.html引入这两个js文件并且打印username时就会报错,说username这个变量没有定义。
向外共享模块作用域中的成员
新建一个17.js文件
输入代码如下
console.log(module);
终端运行结果如下,这说明我们可以通过module中的exports属性向外部文件共享本文件中的一些数据。
新建两个文件
17.js代码
//在外界使用require导入一个自定义模块的时候,得到的成员,
//就是那个模块中,通过module.exports指向的那个对象
const m = require('./18module.exports用法')
console.log(m)
18.js代码
//在一个自定义模块中,默认情况下,module.exports = {}
//向module.exports 对象上挂载username属性
module.exports.username = 'zs'
//向module.exports对象上挂载 sayHellq方法
module.exports.sayHello = function () {
console.log('Hello!')
}
终端运行17.js,发现可以打印出18.js中的一些变量了。
注意点:当module.exports指向一个全新的对象时,旧的对象就不会被输出了。如下图所示,console.log(m2)
不会打印出username和sayHello等变量,而是打印出nickname等变量。
exports和module.exports相同部分。都指向同一个对象。
新建19.js文件
代码如下
console.log(exports);
console.log(module.exports);
// 验证module.exports和exports是否指向同一个对象
console.log(exports === module.exports);
终端运行,我们验证了module.exports和exports是指向同一个对象的。
exports和module.exports不同点。如下图,当打印输出exports时,输出的是gender:男,age:22这个属性,因为最终向外部文件暴露的结果是module.exports指向的对象所决定的。同时,为了防止混乱,建议大家不要在同一个模块中同时使用exports和module.exports。
模块化规范
npm与包
包共享平台,npm地址:https://www.npmjs.com/
。官网首页如下
npm初体验
格式化时间案例
传统的做法如下图所示:
创建两个文件。
20.js代码如下
// 1.定义格式化时间的方法
function dateFormat(dtStr) {
const dt = new Date(dtStr)
const y = dt.getFullYear()
const m = padzero(dt.getMonth() + 1)
const d = padzero(dt.getDate())
const hh = padzero(dt.getHours())
const mm = padzero(dt.getMinutes())
const ss = padzero(dt.getSeconds())
// 使用模板字符串进行拼接,年-月-日 时:分:秒
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}
//定义补零的函数,三目运算符,如果大于9就显示为n,小于9就显示0 n
function padzero(n) {
return n > 9 ? n : '0' + n
}
// 暴露出函数
module.exports = {
dateFormat
}
21.js代码如下
// 导入自定义的格式化时间的模块
const TIME = require('./20格式化时间传统做法');
// 调用方法,进行时间的格式化
const dt = new Date()
const newdt = TIME.dateFormat(dt)
console.log(newdt);
随后终端运行21.js,看到时间格式化成功。
格式化时间的高级做法,使用一些第三方包,可以避免自己去封装一些函数和逻辑。
例如安装moment这个包。在终端输入npm install moment
,然后按回车,就可以了。
新建一个文件22.js,实验该moment包的使用。
获取更详细的用法可以去查官方文档,在npm官网搜索moment
22.js代码如下
// 导入需要的包
const moment = require('moment')
// 具体更详细的用法可以去查官方文档,在npm官网搜索
const dt = moment().format('YYYY-MM-DD HH:mm:ss');
console.log(dt);
终端运行该文件,可以看到打印成功,该方法更简便了。
npm其他注意点
下载一些npm包后,多出的两个文件,我们最好不要手动修改这两个文件中的代码。
另外,如果想下载指定版本的包,以moment举例。终端输入npm i moment@2.22.2
,就会下载2.22.2版本的moment包。
版本号提升规则是:只要前边的版本号提升了,则后边的版本号归0。
包管理配置文件
因为node_modules是存储的下载的包,所以体积大,不方便人们共享,所以需要使用package.json,记录使用的包,当别人运行代码时,再去依照记录单独下载包即可。
package.json中的dvDependenices与dependenices
以moment包举例。
npm i moment //下载到dependenices节点中
npm i moment -D //下载到dvDependenices节点中
解决下包慢问题
镜像(Mirroring)是一种文件存储形式,一个磁盘上的数据在另一个磁盘上存在一个完全相同的副本即为镜像。