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>
<style>
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)));
}
</style>
</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>
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
}
</script>
</body>
</html>
对拆分的代码和解释如下:
// 导入相关模块
const fs = require('fs')
const path = require('path')
// 定义正则表达式,分别匹配 <style></style>和<script></script>
// \s --匹配任意空白字符;\S --匹配任意非空白字符 * --可以出现多次
const regStyle = /<style>[\s\S]*<\/style>/;
const regScript = /<script>[\s\S]*<\/script>/;
// 读取文件
fs.readFile(path.join(__dirname,'./index.html'),'utf8',function(err,dataStr){
// 读取html文件失败
if (err) return console.log("读取html文件失败",err.message);
// 读取html文件成功: 分别拆解 css js html文件
resolveCss(dataStr)
})
// 自定义函数处理 css js html 样式
function resolveCss(htmlStr){
// css
// 使用正则表达式获取页面中的标签
//exec()返回值:是一个数组,
const r1 = regStyle.exec(htmlStr)
// 数组里的内容包含三项,第一项是匹配的内容
// 将提取出来的标签进行替换操作 replace()
const newCss = r1[0].replace("<style>","").replace("</style>","")
// 调用写入方法 将样式写入 .index.css
fs.writeFile(path.join(__dirname,'./index.css'),newCss,function(err){
if (err) return console.log("写入样式失败",err.message);
return console.log("写入样式成功!!");
})
// js
const s1 = regScript.exec(htmlStr)
const newScript = s1[0].replace("<script>","").replace("</script>","")
fs.writeFile(path.join(__dirname,'./index.js'),newScript,function(err){
if (err) return console.log("写入样式失败",err.message);
return console.log("写入样式成功!!");
})
// html
const newHtml = htmlStr.replace(regStyle,'<link rel="stylesheet" href="./index.css">')
.replace(regScript,'<script src="./index.js"></script>')
fs.writeFile(path.join(__dirname,'./clock.html'),newHtml,err =>{
if(err) return console.log("写入样式失败",err.message);
return console.log("写入样式成功!!");
})
}
直接在终端上运行,会在当前目录生成对应拆分出来的三个文件:
拆分后的三个文件分别为:
clock.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>
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
}
读取文件内容并响应给客户端
路径:
// 导入相关模块
const fs = require('fs')
const path = require('path')
const http = require('http')
// 创建 web 服务器
const server = http.createServer()
// 监听 web 服务器 的request事件
server.on('request',(req,res)=>{
// 获取客户端请求的 url地址
// /clock/index.html
// /clock/index.css
// /clock/index.js
const url = req.url
// 把请求的 url地址映射为具体文件的存放路径
// let fpath = path.join(__dirname,url)
//优化用户访问的路径问题
let fpath = '' // 定义一个空路径来存放路径
// 由于不定义 根路径下找不到页面,所以需要定义一下 如果用户输入路径不全 帮用户补全路径
url === '/' ? fpath = path.join(__dirname,'/clock/index.html'):fpath = path.join(__dirname,'/clock',url)
// 根据映射文件路径去读取文件
fs.readFile(fpath,'utf-8',(err,dataStr)=>{
// 读取文件失败,给客户端响应固定的 错误消息
if(err) return res.end('404 Not Found!')
// 读取文件成功后,把对应内容响应给用户
res.end(dataStr)
})
})
// 启动 服务器
server.listen(80,()=>{
console.log('server running at http://127.0.0.1');
})
补充相关正则:
正则中:
\s :匹配任何空白字符,包括空格、制表符、换页符等等。
\S :匹配任何非空白字符
正则常用的四个方法:
test() :验证字符串是否和正则相匹配(匹配返回true,若不匹配返回false)
exec() :将字符串中匹配的内容捕获出来,只会捕获一次。
是一个数组,若无分组则数组里的内容包含三项,分别是匹配的内容、匹配内容的起始索引、原字符串:
- 第一项是匹配的内容
- 第二项是匹配内容的起始索引
- 第三项是原字符串
match() : 将字符串中匹配的内容捕获出来
replace() :替换