模組化規範
1.CommonJS規範
在node中,預設支援的模組化規範叫做CommonJS,
在CommonJS中,一個js檔案就是一個模組
-
CommonJS規範
-
引入模組
-
使用require('模組的路徑')函式來引入模組
-
引入自定義模組時
- 模組名要以 ./ 或 ../ 開頭
- 副檔名可以省略
- 在CommonJS中,如果省略的js檔案的副檔名,node會自動不全副檔名
- 如果沒有改js檔案,會找名字相同的檔案進行引入
- 在CommonJS中,如果省略的js檔案的副檔名,node會自動不全副檔名
-
引入核心模組時
- 直接寫核心模組的名字即可
- 也可以在核心模組前新增
node:
可以加快查詢效率
-
//引入自定義模組 const m1 = require("./m1") //按需引入 const name = require('./m1').name const {name,age,gender} = require('./m1') //引入核心模組 const path = require("path") const path = require("node:path")
在定義模組時,模組中的內容預設是不能被外部看到的
可以透過exports來設定要向外部暴露的內容
訪問exports的方式有兩種:
- exports
- module.exports
- 當我們在其他模組中引入當前模組時,require函式返回的就是exports -
- 可以將希望暴露給外部模組的內容設定為exports的屬性
------------------------------m1.js---------------------------------------- // 可以透過exports 一個一個的匯出值 // exports.a = "孫悟空" // exports.b = {name:"白骨精"} // exports.c = function fn(){ // console.log("哈哈") // } // 也可以直接透過module.exports同時匯出多個值 module.exports = { a: "哈哈", b: [1, 3, 5, 7], c: () =>{ console.log(111) } }
CommonJS執行原理:
-
所有的CommonJS的模組都會被包裝到一個函式中
(function(exports, require, module, __filename, __dirname){ //模組程式碼會被放到這裡 })
exports
:用來設定模組向外部暴露的內容require
:用來引入模組的方法module
:當前模組的引用__filename
:模組的路徑__dirname
:模組所在目錄的路徑
-
2.ES6模組化
Node.js中同樣支援ES模組化,使用模組化無非就是需要注意兩件事匯出和匯入
-
匯出
// 匯出變數(命名匯出) export let name1, name2, …, nameN; export let name1 = …, name2 = …, …, nameN; // 匯出函式(命名匯出) export function functionName(){...} // 匯出類(命名匯出) export class ClassName {...} // 匯出一組 export { name1, name2, …, nameN }; // 重新命名匯出 export { variable1 as name1, variable2 as name2, …, nameN }; // 解構賦值後匯出 export const { name1, name2: bar } = o; // 預設匯出 export default expression; export default function (…) { … } // also class, function* export default function name1(…) { … } // also class, function* export { name1 as default, … }; // 聚合模組 export * from …; // 將其他模組中的全部內容匯出(除了default) export * as name1 from …; // ECMAScript® 2O20 將其他模組中的全部內容以指定別名匯出 export { name1, name2, …, nameN } from …; // 將其他模組中的指定內容匯出 export { import1 as name1, import2 as name2, …, nameN } from …; // 將其他模組中的指定內容重新命名匯出 export { default, … } from …;
-
引入
// 引入預設匯出 import defaultExport from "module-name"; // 將所有模組匯入到指定名稱空間中 import * as name from "module-name"; // 引入模組中的指定內容 import { export1 } from "module-name"; import { export1 , export2 } from "module-name"; // 以指定別名引入模組中的指定內容 import { export1 as alias1 } from "module-name"; import { export1 , export2 as alias2 , [...] } from "module-name"; // 引入預設和其他內容 import defaultExport, { export1 [ , [...] ] } from "module-name"; import defaultExport, * as name from "module-name"; // 引入模組 import "module-name";
需要注意的是,Node.js預設並不支援ES模組化,如果需要使用可以採用兩種方式:
- 方式一:直接將所有js檔案修改為mjs副檔名。
- 方式二:修改package.json中type屬性為module。
3.核心模組
核心模組,是node中自帶的模組,可以在node中直接使用
- window 是瀏覽器的宿主物件 node中是沒有的
- global 是node中的全域性物件,作用類似於window
- ES標準下,全域性物件的標準名應該是
globalThis
-
process
-
表示當前的node程式
-
可以透過改物件獲取程式的資訊,或者對程式做各種操作
-
如何使用
-
process是一個全域性變數,可以直接使用
-
有哪些屬性和方法:
-
process.exit([code狀態碼])
- 結束當前程式,終止node
-
process.nextTick(callback[ ...args])
-
將函式插入到 tick佇列中
-
tick佇列中的程式碼,會在下一次事件迴圈之前執行,會在微任務佇列和宏任務佇列中任務之前執行
setTimeout(()=>{ console.log('111') }) //宏任務佇列 queueMicrotask(()=>{ console.log('222') }) //微任務佇列 process.nextTick(()=>{ console.log('333') }) console.log('444') //執行順序為: 444 -> 333 -> 222 -> 111
-
-
執行順序:
- 呼叫棧
- tick佇列(瞭解)
- 微任務佇列
- 宏任務佇列
-
-
-
path模組
-
表示的路徑
-
透過path可以用來獲取各種路徑
-
要使用path,需要先對其進行引入
-
方法:
-
path.resolve([...paths])
- 用來生成一個絕對路徑
- 直接呼叫resolve,則返回當前的工作目錄
- 注意,我們透過不同的方式執行程式碼時,它的工作目錄是有可能發生變化的
-
如果將一個相對路徑作為引數:
- 則resolve會自動將其轉換為絕對路徑
- 此時根據工作目錄的不同,他所產生的絕對路徑也不同
-
一般會將一個絕對路徑作為第一個引數
- 一個相對路徑作為第二個引數
- 這樣它會自動計算出最後的路徑
//引入模組 const path = require('node:path') //以後在使用路徑時,儘量透過path.resolve()來生成路徑 const result = path.resolve(__dirname, './hello.js')
-
-
-
fs模組
-
fs用來幫助node來操作磁碟中的檔案
-
檔案操作也就是所謂的I/O流,input output
-
使用fs模組,同樣需要引入
-
fs.readFileSync()
-
readFileSync() 同步的讀取檔案的方法,會阻塞後面的程式碼執行
-
當我們透過fs模組讀取磁碟中的資料時,讀取到的資料總會一Buffer物件的形式返回
-
Buffer是一個臨時用來儲存資料的緩衝區
//引入模組 const path = require('node:path') const fs = require('node:fs') const buffer = fs.readFileSync(path.resolve(__dirname, './hello.txt')) console.log(buffer.toString()) //把Buffer資料轉換為字串型別
-
-
fs.readFile()
-
非同步的讀取檔案的方法
-
方法1:回撥函式式
const path = require('node:path') const fs = require('node:fs') fs.readFile(path.resolve(__dirname, './hello.js'),(err,buffer)=>{ if(err){ console.log("出錯了~") } else { console.log(buffer.toString()) } })
-
方法2:promise式
const path = require('node:path') const fs = require('node:fs/promises') fs.readFile(path.resolve(__dirname, './hello.js')) .then(buffer=>{ console.log(buffer.toString()) }) .catch(e=>{ console.log('出錯了,有問題', e.message) })
-
方法3:async和await式
;(async ()=>{ try { const buffer = await fs.readFile(path.resolve(__dirname, './hello.js')) console.log(buffer.toString()) } catch(e){ console.log(’出錯了....) } })()
-
-
-
fs.appendFile()
- 建立新檔案,或將資料新增到已有檔案中
-
fs.mkdir()
- 建立目錄
-
fs.rmdir()
- 刪除目錄
-
fs.rm()
- 刪除目錄
-
fs.rename()
- 重新命名
-
fs.copyFile()
- 複製檔案
-
-
//實現複製一個檔案 //1.讀取檔案中的內容 const path = require('node:path') const fs = require('node:fs/promises') fs.readFile(path.reslove(__dirname, './hello.txt')) .then(buffer =>{ //2.複製檔案中的 return fs.appendFile(path.resolve(__dirname, './world.txt'), buffer) }) .then(()=>{ console.log('操作結束') }) .catch(err =>{ console.log('出錯了..') })