Переглянути джерело

feat: 添加一些常用模块

liucong5 2 роки тому
батько
коміт
719e9b3549

+ 211 - 2
NodeJS/README.md

@@ -609,7 +609,7 @@ export {
 import { name, sayHello } from "./bar.js"
 ```
 
-> 必须指定确定文件后缀,原生ESM不会像 CJS 去搜索文件
+<!-- > 必须指定确定文件后缀,原生ESM不会像 CJS 去搜索文件 -->
 
 2. 起别名
 
@@ -772,5 +772,214 @@ console.log(obj.name)
 obj.name = "main"
 ```
 
-## 常见的内置模块解析
+### CJS 和 ESM 交互
 
+- 通常情况下 CJS 不能加载 ESM
+
+因为 CJS 是同步加载;ESM 必须经过静态分析,此时并没有运行JS代码
+
+但是某些平台在实现的时候可以对代码进行针对性的解析,也可能会支持;但是Node是不支持的 
+
+- 多数情况下,ESM 可以加载 CJS
+
+ESM 在加载 CJS 时,会将其 module.exports 导出的内容作为 default 导出方式来使用
+
+这个依然需要看具体实现,比如webpack支持,Node 新版本支持
+
+```js
+// bar.js
+const name = "bar";
+
+module.exports = {
+    name
+}
+```
+
+```js
+// main.mjs
+import foo from './bar.js';
+
+console.log(foo.name)
+```
+
+> 为什么是 mjs 后缀,因为如果要模块支持 ESM 需要设置 package.json 或者将 js 后缀改为 mjs
+
+## node常见的内置模块
+
+### Path
+
+path 模块用于对路径和文件进行处理,提供了很多好用的方法
+
+由于 MacOs/Linux 和 Windows 的文件层级符号不同,所以对路径直接硬编码会导致平台兼容性问题,因此推荐使用 path 模块进行路径处理,而不是手动编写 `bastPath + "\\" + filename`
+
+[path官方文档](https://nodejs.org/dist/latest-v18.x/docs/api/path.html)
+
+```js
+const path = require('path');
+// import path from 'path' // ESM 导入
+
+const bastPath = 'Temp';
+const rootPath = "/User/root/Temp"
+const filename = 'test.txt'
+
+// resolve 用于路径拼接
+const fileFullPath = path.resolve(bastPath, filename)
+const fileFullPath2 = path.resolve(rootPath, filename)
+
+console.log(fileFullPath);  // 以 当前运行文件夹为相对路径
+console.log(fileFullPath2); // 以 根目录 为绝对路径
+
+// 获取路径信息
+const TempFilePath = "/User/root/config.txt"
+const TempFileDir = "/User/root/config"
+
+console.log(path.dirname(TempFilePath))     // /User/root
+console.log(path.dirname(TempFileDir))      // /User/root
+
+console.log(path.basename(TempFilePath))    // 文件名 config.txt
+
+console.log(path.extname(TempFilePath))     // 文件后缀 .txt
+
+// join 路径拼接
+const TempBasePath = '/User/root'
+const TempFileName = 'acb.txt'
+
+console.log(path.join(TempBasePath, TempFileName))
+
+// resolve 路径拼接 对比 join resolve 会多判断判断路径字符串开头是否有 "/" "./" "../"
+console.log(path.resolve(TempBasePath, TempFileName))
+```
+
+### FS
+
+File System 简称 FS,表示文件系统
+
+[官方文档中对 FS 的解释](https://nodejs.org/dist/latest-v18.x/docs/api/fs.html)
+
+借助 node 封装的文件系统,可以在任何操作系统上直接操作文件
+
+FS 的 API 非常多,这些 API 大多数提供三种操作方式
+
+1. 同步操作文件:代码会阻塞,不会继续执行
+2. 异步回调函数操作文件:代码不会被阻塞,需要传入回调函数,当获取到结果时,回调函数执行
+3. 异步`Promise`操作文件:代码不会被阻塞,通过`fs.promises`调用方法操作,会返回一个`Promise`,可以通过`then`、`catch`进行处理
+
+```js
+const fs = require('fs')
+
+const filepath = './tempfil.txt'
+
+// 同步执行
+// const info = fs.statSync(filepath)
+// console.log("后续需要执行的代码")
+// console.log(info);
+
+// 异步操作
+// fs.stat(filepath, (err, info) => {
+//     if(err) {
+//         console.log(err)
+//     }
+//     else {
+//         console.log(info);
+//     }
+// })
+// console.log("后续需要执行的代码")
+
+// promise
+fs.promises.stat(filepath).then((info) => {
+    console.log(info);
+}).catch(err => {})
+console.log("后续需要执行的代码")
+```
+
+#### 文件描述符
+
+什么是文件描述符?为什么需要文件描述符?
+
+```js
+fs.open('./tempfil.txt', (err, fd) => {
+    if(err) {
+        console.log(err);
+        return;
+    }
+    console.log(fd);
+})
+```
+
+> fd 即 文件描述符
+
+fs 的 API 如果以 **f** 开头,那么一般都是需要传入 文件描述符 的 API
+
+#### 写文件
+
+`fs.writeFile(file, data[, options], callback)` API 除了文件路径、文本信息外还有一个 options 的选项参数
+
+options 包括 `encoding`、`mode`、`flag` 和 `signla`
+
+[flags的选项及其含义](https://nodejs.org/dist/latest-v18.x/docs/api/fs.html#file-system-flags)
+
+| flag | 含义 |
+| --- | --- |
+| w | 打开文件写入,默认值 |
+| w+ | 打开文件进行读写,如果不存在创建文件 |
+| r+ | 打开文件进行读写,如果不存在抛出异常 |
+| r | 打开文件读取,读取时的默认值 |
+| a | 打开要写入的文件,将流放在文件末尾。如果不存在则创建文件 |
+| a+ | 打开文件进行读写,将流放在文件末尾。如果不存在则创建文件 |
+
+```js
+const fs = require('fs')
+
+const filepath = './tempfil.txt'
+
+const fileContent = 'file content ....'
+
+// 回调写入文件
+fs.writeFile(filepath, fileContent, {flag : "a"}, (err) => {
+    console.log(err)
+});
+```
+
+至于默认编码 `encoding` 使用的是 `utf-8`
+
+#### 读文件
+
+那么如何读取文件呢?肯定是 `readFile` 相关接口了
+
+```js
+fs.readFile(filepath, (err, data) => {
+    if(err) {
+        console.log(err)
+    }
+    else {
+        console.log(data)   // 输出 buffer 十六进制
+    }
+})
+```
+
+以 `fs.readFile` 为例,直接输入 data 内容 其实是一个 buffer 对象,是文件的 **十六进制** 内容
+
+为了输出的是十六进制内容,而不是具体文字内容呢?是因为没有指定字符串,fs并不知道应该如何解析
+
+```js
+fs.readFile(filepath, {encoding: 'utf-8'}, (err, data) => {
+    if(err) {
+        console.log(err)
+    }
+    else {
+        console.log(data)   // 输出 buffer 十六进制
+    }
+})
+```
+
+如果输出乱码,那么就是文本的读取编码设置错误
+
+#### 文件夹相关操作
+
+创建文件夹: `fs.mkdir` 
+
+一般创建文件夹是会先判断文件夹是否存在 `fs.existsSync` ,如果文件不存在那么需要创建文件夹,如果文件不存在就不需要创建
+
+读取文件夹下所有的文件: `fs.readdir`
+
+文件夹重命名:

+ 19 - 0
NodeJS/TestJS/fs_test.js

@@ -0,0 +1,19 @@
+const fs = require('fs')
+
+const filepath = './tempfil.txt'
+
+const fileContent = '测试内容....'
+
+// 回调写入文件
+fs.writeFile(filepath, fileContent, (err) => {
+    console.log(err)
+});
+
+fs.readFile(filepath, {encoding: 'utf-8'}, (err, data) => {
+    if(err) {
+        console.log(err)
+    }
+    else {
+        console.log(data)   // 输出 buffer 十六进制
+    }
+})

+ 5 - 0
NodeJS/TestJS/js-module/cjs_esm/bar.js

@@ -0,0 +1,5 @@
+const name = "bar";
+
+module.exports = {
+    name
+}

+ 0 - 0
NodeJS/TestJS/js-module/cjs_esm/index.js


+ 3 - 0
NodeJS/TestJS/js-module/cjs_esm/main.mjs

@@ -0,0 +1,3 @@
+import foo from './bar.js';
+
+console.log(foo.name)

+ 33 - 0
NodeJS/TestJS/path_test.js

@@ -0,0 +1,33 @@
+const path = require('path');
+
+const bastPath = 'Temp';
+const rootPath = "/User/root/Temp"
+const filename = 'test.txt'
+
+// resolve 用于路径拼接
+const fileFullPath = path.resolve(bastPath, filename)
+const fileFullPath2 = path.resolve(rootPath, filename)
+
+console.log(fileFullPath);  // 以 当前运行文件夹为相对路径
+console.log(fileFullPath2); // 以 根目录 为绝对路径
+
+// 获取路径信息
+const TempFilePath = "/User/root/config.txt"
+const TempFileDir = "/User/root/config"
+
+console.log(path.dirname(TempFilePath))     // /User/root
+console.log(path.dirname(TempFileDir))      // /User/root
+
+console.log(path.basename(TempFilePath))    // 文件名 config.txt
+
+console.log(path.extname(TempFilePath))     // 文件后缀 .txt
+
+// join 路径拼接
+const TempBasePath = '/User/root'
+const TempFileName = 'acb.txt'
+
+console.log(path.join(TempBasePath, TempFileName))
+
+// resolve 路径拼接 对比 join resolve 会多判断判断路径字符串开头是否有 "/" "./" "../"
+console.log(path.resolve(TempBasePath, TempFileName))
+

+ 1 - 0
NodeJS/TestJS/tempfil.txt

@@ -0,0 +1 @@
+测试内容....