03_path模块
path
1、path路径模块
1.1、了解path

1.2、导入path模块
与 fs 模块相同,path模块的导入方式也是通过require函数进行引用,通过传递字符串的方式,得到一个path模块对象,并且这个模块对象我们可以使用一个常量来进行接收

2、path的一些常用方法
2.1、path.join()
- 使用path.join()方法,可以将 多个路径片段拼接成完整的字符串路径
- 语法格式如下
- 举个例子
1、关于 ../ 和 ./
- 使用相对路径的时候,../和./会抵消掉左边离他最近的一个目录
- 我们来看个例子
2、与__dirname一起使用
-
本质上 __dirname也是一个字符串对象,所以可以作为path.join()方法当中的参数
-

-
// 3、与__dirname一起使用 // 引入fs模块 const fs = require("fs") // 读取文件信息 fs.readFile(path.join(__dirname,"../","demo2_使用readFile语法/text/成绩.txt"),"utf-8",(err,dataStr)=>{ if(err){ return } console.log(dataStr); })
-
-
代码解析
3、注意
今后凡是涉及到路径拼接问题的,都要使用 path.join()方法进行处理,不要直接使用 + 进行字符串拼接

仔细看一下这个代码就知道了,./返回上一级目录,但是使用 +号拼接就会出现拼接出来是个 . 的情况

2.2、path.basename()
- 获取路径中的文件名
- 使用该函数,可以获取一格路径下的,最后一部分,也就是咱们的文件部分,通常用这个方法来获取路径当中的文件名,使用格式如下
- 第二个参数实际上指的是,如果你传递了这个参数,那么就会将得到的文件的后缀删除掉,也就是扩展名
- 说人话就是,只需要拿到文件名称,不需要扩展名,那么就可以传递第二个参数
测试1

// 引入path模块
const path = require("path")
// 这里配置一个需要读取文件的路径
var needPath = "D:\\技能学习\\node\\demo2_使用readFile语法\\text\\成绩.txt";
// 使用path.basename()函数,这里不传递第二个参数
var callPath = path.basename(needPath)
console.log('basename提取到的文件名为:'+ callPath);

测试2
第二个参数为文件的扩展名,或者说后缀

第二个参数是字符串,也就是说,实际上第二个参数的作用就是割裂掉这个字符串

那如果第二个参数,根本就不是这个文件名的后缀呢?

2.3、path.extname()
使用该函数,可以获取“路径中,文件名的扩展名部分(后缀)”

应该是以 . 作为条件进行分割的,取出.右边的路径,无论这个路径是否合理



3、时钟案例
3.1、需求分析
-
这里有一个html文件
-
在这个HTML文件当中,html代码,css代码,和js代码是一体的
-
<!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> </head> <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> <body> <div class="box"> <div id="HH">00</div> <div>:</div> <div id="mm">00</div> <div>:</div> <div id="ss">00</div> </div> </body> <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> </html>
-
-
我们现在需要通过path模块,fs模块,对这个html文件进行拆分,将其拆分成css,html,和js文件,同时,需要在html文件当中通过外链的形式来导入我们的css和js文件
3.2、步骤解读
- 首先,引入我们的path模块和fs模块
- 其次,我们需要创建正则表达式来匹配我们的css内容和js内容

- 解读部分

- 使用fs模块读取html文件,使用path模块的join函数对路径进行拼接,增强代码维护性和移植性
- 自定义函数,在这个函数当中完成对css文件的写入操作
- 这个时候需要使用正则表达式了,但是我应该怎么读取?
- fs可以读取到这个index.html文件,但是我应该如何将css的部分拆分出来?
- .exec()函数
- 格式: 正则表达式.exec(需要匹配的字符串)

- 返回值

- 之前的想法是没错的,String对象当中的match也可以做到,但是我没考虑返回值的问题
3.3、思想误区

- 先看下这个代码吧,我犯了个什么错误?
- 我想的是,给css和js的函数,外增加一个额外的函数供他们调用
- 因为需要正则表达式来对匹配内容进行读取,所以readFile()是必须要用的
- 那我就专门为readFile这个函数单独封装一个方法,供二者调用(误区)
- 那么,readFile被调用了,没问题,那么剩下的css函数和js函数谁来调用?
- 在前端里面,我们调用函数大可以使用window这个全局对象来对js代码进行解读和函数调用
- 而在node当中,谁来调用?node对象吗?node对象如何调用一个我自定义的方法?应该是有的,但是现在我没法接触
- 这就是一个思想误区
- 所以解决问题的方法,就是用 可以被node直接调用的API对象来对我自定义的方法进行调用和解析
3.4、改进
- 引入fs模块和path模块
- 编写css和js内容的正则表达式
- 为写入css文件和js文件还有html文件做准备 == fs.wirteFile()
- .exec():String对象的一个正则表达式匹配函数
- 语法:String(这里代表的是正则表达式).exec(需要进行匹配的字符串)
- .match():与exec函数同理,二者用法相似
- 语法:String(需要进行匹配的字符串).match(这里放正则表达式)
- 二者的返回值都是数组对象,索引为0的内容就是我们匹配出来的内容
- .exec():String对象的一个正则表达式匹配函数
- 对写入css文件的函数和js文件的函数进行标签的去除 == replace()

- 当然,参数1也可以是正则表达式,这样可以表示一片区域的内容替换

- 我们肯定是需要通过fs模块的writeFile进行文件写入,那就单独为其封装一个方法
- 最后,通过fs.readFile(),函数进行index.html文件的读取,然后在这个函数当中对三个函数进行调用,避免异步的问题发生
3.5、代码
/*
* @Author: WavesBright 1336959829@qq.com
* @Date: 2022-09-28 14:56:43
* @LastEditors: WavesBright 1336959829@qq.com
* @LastEditTime: 2022-09-28 17:06:14
* @FilePath: \node\demo3_path模块\04_时钟(综合案例).js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
// 1、引入path模块和fs模块
const path = require('path')
const fs = require('fs')
// 2、创建正则表达式,对css内容和js内容进行匹配
/*
//:代表这是一个正则表达式
<style><\/style>:以<style>开头,以</style>结尾
\的目的是因为在代码当中的转译问题,所以需要正斜杠
[]:匹配区间,
\s:任意空字符,\S:任意非空字符
*:代表匹配任意多个
*/
const meatInCss = /<style>[\s\S]*<\/style>/
const meatInJs = /<script>[\s\S]*<\/script>/
// 3、使用fs模块读取我们的html文件
var readPath = "clock/index.html"
fs.readFile(path.join(__dirname,readPath),"utf-8",(err,dataStr)=>{
if(err){
return
}
// 写入css文件
writeInCss(dataStr)
// 写入js文件
writeInJs(dataStr)
// 更新html文件,引入外链
writeInHtml(dataStr)
})
// 定义一个函数,来写入css样式(fs.writeFile)
/**
* css写入内容
* @param {匹配到的css模块内容} writeContent
*/
function writeInCss(writeContent){
// 对readFile读取的内容进行拆分
var str = meatInCss.exec(writeContent)
// 去除头部和尾部的<style>标签
var newCss = str[0].replace("<style>","").replace("</style>","")
// 调用自定义封装的写入方法
writeToFile("clock/index.css",newCss)
}
// 定义一个函数,来写入js样式(fs.writeFile)
/**
* js写入内容
* @param {匹配到的css模块内容} writeContent
*/
function writeInJs(writeContent){
// 对readFile读取的内容进行拆分
var str = meatInJs.exec(writeContent)
// 去除头部和尾部的<script>标签
var newJs = str[0].replace("<script>","").replace("</script>","")
// 调用自定义封装的写入方法
writeToFile("clock/index.js",newJs)
}
/**
* 重新写入HTML文件
* @param {读取到的HTML文件内容} writeContent
*/
function writeInHtml(writeContent){
// replace的第二个用法,参数1可以是一个正则表达式对象
// 1、将<style>标签的内容替换为外链,2、将<script>标签的内容替换为外链
var str = writeContent.replace(meatInCss,"<link rel='stylesheet' href='./index.css' />")
.replace(meatInJs,"<script src='./index.js' />")
// 调用封装方法写入内容
writeToFile("clock/index.html",str)
}
/**
* 为写入css和js单独封装的fs模块写入方法
* @param {*} path 写入的文件路径是?
* @param {*} writeContent 写入的文件内容是?
*/
function writeToFile(writePath,writeContent){
// 使用fs模块对其进行写入(不存在改文件,则新建)
fs.writeFile(path.join(__dirname,writePath),writeContent,(err)=>{
if(!err){
console.log("写入成功");
}else{
console.log(err + "写入失败");
}
})
}
3.6、总结
整体来说这个案例还是蛮有意思的,虽然泛用性比较小,但是其中的一些函数,String对象当中的函数,在以后可能会经常用到,还是有收获的
- .exec()
- .mathc()
- .replace()








浙公网安备 33010602011771号