node中的模塊: commonJs
模塊是Node.js 應(yīng)用程序的基本組成部分魁索,文件和模塊是一一對應(yīng)的。換言之晨逝,一個 Node.js 文件就是一個模塊蜈项,這個文件可能是JavaScript 代碼兰迫、JSON 或者編譯過的C/C++ 擴(kuò)展。
- 一個文件就是一個模塊
采用module.exports
暴露方法和屬性
通過require
外部可以導(dǎo)入
每個模塊內(nèi)部雅采,module變量代表當(dāng)前模塊。這個變量是一個對象,它的exports屬性(即module.exports)是對外的接口。加載某個模塊,其實是加載該模塊的module.exports屬性急前。
var x = 5;
var addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;
上面代碼通過module.exports輸出變量x和函數(shù)addX。
require方法用于加載模塊瀑构。
var example = require('./example.js');
//相當(dāng)于 example = module.exports
console.log(example.x); // 5
console.log(example.addX(1)); // 6
node中的模塊和es6中的模塊有一定的區(qū)別裆针,本文不做比較,這里我們后面再做了解寺晌。因為現(xiàn)在nodejs 不支持es6語法世吨,所有在webpack 的配置文件里面還要通過require來導(dǎo)入。
包的入口文件index.js
在組成一個包的所有子模塊中呻征,需要有一個入口模塊耘婚,入口模塊的導(dǎo)出對象被作為包的導(dǎo)出對象。例如有以下目錄結(jié)構(gòu)陆赋。
- /home/user/lib/
- cat/
head.js
body.js
main.js
使用require('/home/user/lib/cat/main')能達(dá)到目的沐祷,但是入口模塊名稱出現(xiàn)在路徑里看上去不是個好主意。
當(dāng)模塊的文件名是index.js攒岛,加載模塊時可以使用模塊所在目錄的路徑代替模塊文件路徑赖临,因此以下兩條語句等價。
var cat = require('/home/user/lib/cat');
var cat = require('/home/user/lib/cat/index');
這樣處理后灾锯,就只需要把包目錄路徑傳遞給require函數(shù)兢榨,感覺上整個目錄被當(dāng)作單個模塊使用,更有整體感挠进。
package.json
如果想自定義入口模塊的文件名和存放位置色乾,就需要在包目錄下包含一個package.json文件誊册,并在其中指定入口模塊的路徑领突。上例中的cat模塊可以重構(gòu)如下。
- /home/user/lib/
- cat/
+ doc/
- lib/
head.js
body.js
main.js
+ tests/
package.json
其中package.json內(nèi)容如下案怯。
{
"name": "cat",
"main": "./lib/main.js"
}
如此一來君旦,就同樣可以使用require('/home/user/lib/cat')的方式加載模塊。NodeJS會根據(jù)包目錄下的package.json找到入口模塊所在位置嘲碱。 這樣他就不會默認(rèn)去找cat文件夾下的index文件了金砍,而是通過package.json來找入口文件。
內(nèi)置FS模塊
Node.js 提供一組類似 UNIX(POSIX)標(biāo)準(zhǔn)的文件操作API麦锯。 Node 導(dǎo)入文件系統(tǒng)模塊(fs)語法如下所示:
const fs = require("fs")
異步和同步
Node.js 文件系統(tǒng)(fs 模塊)模塊中的方法均有異步和同步版本恕稠,例如讀取文件內(nèi)容的函數(shù)有異步的 fs.readFile() 和同步的 fs.readFileSync()。
異步的方法函數(shù)最后一個參數(shù)為回調(diào)函數(shù)扶欣,回調(diào)函數(shù)的第一個參數(shù)包含了錯誤信息(error)鹅巍。
建議大家使用異步方法千扶,比起同步,異步方法性能更高骆捧,速度更快澎羞,而且沒有阻塞。
fs常用方法
這里介紹練習(xí)的方法都是異步的方法敛苇,同步方法使用這里不做介紹
- fs.stat
檢測傳入的路徑是文件還是目錄
fs.stat('./html',function(err,data){
if(err){
console.log(err);
return;
}
console.log(`是文件嗎:${data.isFile()}`);
console.log(`是目錄嗎: ${data.isDirectory()}`);
})
fs.stat('./html/app.html',function(err,data){
if(err){
console.log(err);
return;
}
console.log(`是文件嗎:${data.isFile()}`);
console.log(`是目錄嗎:${data.isDirectory()}`);
})
- fs.mkdir
創(chuàng)建目錄
path 將創(chuàng)建的目錄路徑
mode 目錄權(quán)限(讀寫權(quán)限)妆绞,默認(rèn)777
callback 回調(diào),傳遞異常參數(shù)err
如果目錄不存在 就創(chuàng)建枫攀, 如果存在 就報錯 改路徑已經(jīng)存在
fs.mkdir(`./css`,function(err,data){
if(err){
console.log(err);
return;
}
console.log('創(chuàng)建成功');
})
- fs.writeFile
創(chuàng)建寫入文件
如果文件不存在就創(chuàng)建 如果文件存在 就替換
fs.writeFile('./html/app.html','你好 nodeJs', (err) => {
if(err){
console.log(err);
return;
}
console.log('創(chuàng)建寫入文件成功');
})
- fs.appendFile
如果文件不存在就創(chuàng)建然后寫入 如果存在就在內(nèi)容后面追加
fs.appendFile('./css/base.css','body{color:red}',(err)=>{
if(err){
console.log(err);
return;
}
console.log('appendFile 成功')
})
fs.appendFile('./css/base.css','h2{font-size:12px}',(err)=>{
if(err){
console.log(err);
return;
}
console.log('appendFild 成功');
})
- fs.readDir
查看目錄
會列出該路徑下的文件和文件夾(只包含兒子括饶,不包含孫子)
fs.readdir('./html',(err,data)=> {
if(err){
console.log(err);
return;
}
console.log(data);
})
- fs.rename
功能:
1、 重命名文件 2来涨、移動文件(相當(dāng)于重命名路徑)
fs.rename('./html/app.html','./html/index.html',(err) => {
if(err){
console.log(err);
return;
}
console.log('重命名成功');
})
fs.rename('./css/base.css','./html/index.css',err =>{
if(err){
console.log(err);
return;
}
console.log('移動成功');
})
- fs.rmdir
刪除目錄 但是只能刪除空的目錄
fs.rmdir('./html/html2/',err => {
if(err){
console.log(err);
return;
}
console.log('刪除目錄成功');
})
- fs.unlink
刪除文件
fs.unlink('./html/html2/index.html',err => {
if(err){
console.log(err);
return;
}
console.log('刪除文件成功');
})
文件流
閱讀流
// 創(chuàng)建一個只讀的流
const createRead = fs.createReadStream('./data/input.txt');
let count = 0;
let str = '';
// 當(dāng)有數(shù)據(jù)可讀時觸發(fā)
createRead.on('data',(data)=>{
str=str+data;
count++;
})
// 當(dāng)沒有更多的數(shù)據(jù)可讀時觸發(fā)
createRead.on('end',()=> {
console.log(str);
console.log(count)
})
// 發(fā)生錯誤事觸發(fā)
createRead.on('err',(err)=>{
console.log(err.stack);
})
寫入的流
// 寫入的流
const fs = require('fs');
const data = '測試測試測試測試測試測試測試測試測試測試測試測試測試測試';
let str='';
// 創(chuàng)建一個寫入的流 并寫入到 ./data/data.txt文件中
const writeStream = fs.createWriteStream('./data/data.txt');
for(var i=0;i<500;i++){
str = str + `${data}${i}\r\n`;
}
// 寫入data數(shù)據(jù) 并設(shè)置格式
writeStream.write(str,'UTF8');
writeStream.end();//如果不寫 end 不會觸發(fā)finish事件
writeStream.on('finish',()=>{
console.log('寫入完成');
})
writeStream.on('err',(err)=>{
console.log(err.stack);
})
參考文章: