1.0、變數作用域
(1)、在瀏覽器端使用var或不使用關鍵字定義的變數屬於全域性作用域,也就是可以使用window物件存取。【相關教學推薦:、】
<script>
var a = 100;
(function () {
b = 200;
})();
console.log(window.a, a);
console.log(window.b, b);
</script>
登入後複製
結果:
(2)、在Node.js中沒有window物件
(3)、在Node.js的互動環境下,定義的變數屬於global,global是類似瀏覽器端的window物件
(4)、在模組中(檔案中)有global物件,使用關鍵字var,let,const定義的成員不屬於global物件,僅在當前模組中有效,而不使用關鍵字定義的物件屬於global物件。
var a=100;
b=200;
let c=300;
const d=400;
console.log(global);
console.log(global.a);
console.log(global.b);
console.log(global.c);
console.log(global.d);
登入後複製
終端輸出:
1.1、模組概要
早期的javascript版本沒有塊級作用域、沒有類、沒有包、也沒有模組,這樣會帶來一些問題,如複用、依賴、衝突、程式碼組織混亂等,隨著前端的膨脹,模組化顯得非常迫切。
前端模組化規範如下:
常見的的JavaScript模組規範有:CommonJS、AMD、CMD、UMD、原生模組化。
雖然我們學習過ES6的模組化但是ES6與NodeJS使用不同的模組化規範,單獨學習NodeJS的模組化非常有必要。
模組化是指解決一個複雜問題時,自頂向下逐層把系統劃分成若干模組的過程。對於整個系統來說,模組是可組合、分解和更換 的單元。
JavaScript在早期的設計中就沒有模組、包、類的概念,開發者需要模擬出類似的功能,來隔離、組織複雜的JavaScript程式碼,我們稱為模組化。
模組就是一個實現特定功能的檔案,有了模組我們就可以更方便的使用別人的程式碼,要用什麼功能就載入什麼模組。
模組化開發的四點好處:
(1)、 避免變數汙染,命名衝突
(2)、提高程式碼複用率
(3)、提高了可維護性
(4)、方便依賴關係管理
nodejs中根據模組的來源不同,將模組分為了3大類,分別是:
模組作用域。
和函數作用域類似,在自定義模組中定義的變數、方法等成員,只能在當前模組內被存取,這種模組級別的存取限制,叫做模組作用域。
模組作用域的好處:防止了全域性變數汙染的問題
1.2、CommonJS
CommonJS就是一個JavaScript模組化的規範,該規範最初是用在伺服器端NodeJS中,前端的webpack也是對CommonJS原生支援的。
根據這個規範
(1)、每一個檔案就是一個模組,其內部定義的變數是屬於這個模組的,不會對外暴露,也就是說不會汙染全域性變數。
(2)、匯入自定義的模組時路徑需要以./或../開始,同一路徑下也不能省略。
(3)、如果反覆多次require模組,只載入一次。
(4)、require引入模組時,字尾名.js可以省略
(5)、每個模組檔案都是一個獨立的函數級作用域,在其它模組中不能直接存取
m1.js:
console.log("這是模組m1");
let a=100;
b=200;
登入後複製
m2.js
var m11=require("./m1");
console.log(a);
console.log(b);
登入後複製
結果:
從上面的範例可以看出a在模組2中是存取不到的,模組其實就是一個封閉的函數:
m1.js的程式碼如下:
console.log("這是模組m1");
let a=100;
b=200;
//輸出當前函數
console.log(arguments.callee+"");
登入後複製
實際輸出結果:
function (exports, require, module, __filename, __dirname) {
console.log("這是模組m1");
let a=100;
b=200;
//輸出當前函數
console.log(arguments.callee+"");
}
登入後複製
(6)、每個模組中都包含如下5個物件:
exports:匯出物件,預設為{}
require:匯入函數,使用該函數可以實現模組的依賴
module:模組資訊,用於記錄當前模組的所有資訊
__filename:當前模組的檔案全路徑,含檔名
__dirname:當前模組的檔案路徑不含檔名
(7)、使用exports或module.exports物件可以將當前模組中需要匯出的內容暴露出去。
m1.js
let a=100;
let b=()=>{
return 200;
};
exports.a=a;
exports.b=b;
登入後複製
m2.js
const m1=require("./m1");
console.log(m1);
console.log(m1.a);
console.log(m1.b());
登入後複製
結果:
(8)、匯入模組內容可以結合結構語法
m1.js
exports.a=100;
exports.b=function(){
return 200;
};
登入後複製
m2.js
const {a,b:fun}=require("./m1");
console.log(a);
console.log(fun());
登入後複製
結果:
1.3、NodeJS中使用CommonJS模組管理
CommonJS的核心思想就是通過 require 方法來同步載入所要依賴的其他模組,然後通過 exports 或者 module.exports 來匯出需要暴露的介面。
CommonJS API編寫應用程式,然後這些應用可以執行在不同的JavaScript直譯器和不同的主機環境中。
2009年,美國程式設計師Ryan Dahl創造了node.js專案,將javascript語言用於伺服器端程式設計。這標誌"Javascript模組化程式設計"正式誕生。因為老實說,在瀏覽器環境下,以前沒有模組也不是特別大的問題,畢竟網頁程式的複雜性有限;但是在伺服器端,一定要有模組,與作業系統和其他應用程式互動,否則根本沒法程式設計。NodeJS是CommonJS規範的實現,webpack 也是以CommonJS的形式來書寫。
CommonJS定義的模組分為:{模組參照(require)} {模組定義(exports)} {模組標識(module)}
//require()用來引入外部模組;
//exports物件用於匯出當前模組的方法或變數,唯一的匯出口;
//module物件就代表模組本身。
登入後複製
Nodejs的模組是基於CommonJS規範實現的,通過轉換也可以執行在瀏覽器端。
特點:
根據commonJS規範,一個單獨的檔案是一個模組,每一個模組都是一個單獨的作用域,也就是說,在該模組內部定義的變數,無法被其他模組讀取,除非為global物件的屬性。
模組擁有像函數一樣的函數級作用域:
每個模組內部,module變數代表當前模組
module變數是一個物件,它的exports屬性(即module.exports)是對外的介面
載入某個模組,其實是載入該模組的module.exports屬性。require()方法用於載入模組。
模組只有一個出口,module.exports物件,我們需要把模組希望輸出的內容放入該物件。
mathLib.js模組定義
var message="Hello CommonJS!";
module.exports.message=message;
module.exports.add=(m,n)=>console.log(m+n);
登入後複製
在 Node.js 中,建立一個模組非常簡單,如下我們建立一個 'main.js' 檔案,程式碼如下:
var hello = require('./hello');
hello.world();
登入後複製
以上範例中,程式碼 require('./hello') 引入了當前目錄下的hello.js檔案(./ 為當前目錄,node.js預設字尾為js)。
Node.js 提供了exports 和 require 兩個物件,其中 exports 是模組公開的介面,require 用於從外部獲取一個模組的介面,即所獲取模組的 exports 物件。
接下來我們就來建立hello.js檔案,程式碼如下:
exports.world = function() {
console.log('Hello World');
}
登入後複製
在以上範例中,hello.js 通過 exports 物件把 world 作為模組的訪 問介面,在 main.js 中通過 require('./hello') 載入這個模組,然後就可以直接訪 問main.js 中 exports 物件的成員函數了。
有時候我們只是想把一個物件封裝到模組中,格式如下:
module.exports = function() { // ...}
登入後複製
例如:
//hello.js
function Hello() {
varname;
this.setName = function(thyName) {
name = thyName;
};
this.sayHello = function() {
console.log('Hello ' + name);
};
};
module.exports = Hello;
登入後複製
這樣就可以直接獲得這個物件了:
//main.js
var Hello = require('./hello');
hello = new Hello();
hello.setName('BYVoid');
hello.sayHello();
登入後複製
模組介面的唯一變化是使用 module.exports = Hello 代替了exports.world = function(){}。 在外部參照該模組時,其介面物件就是要輸出的 Hello 物件本身,而不是原先的 exports。
載入模組用require方法,該方法讀取一個檔案並且執行,返回檔案內部的module.exports物件。
在用require載入自定義模組期間,可以省略.js這個字尾名。
myApp.js 模組依賴
var math=require('./mathLib');
console.log(math.message);
math.add(333,888);
登入後複製
3、測試執行
安裝好node.JS
開啟控制檯,可以使用cmd命令,也可以直接在開發工具中存取
執行
也許你已經注意到,我們已經在程式碼中使用了模組了。像這樣:
var http = require("http");
...
http.createServer(...);
登入後複製
Node.js中自帶了一個叫做"http"的模組,我們在我們的程式碼中請求它並把返回值賦給一個本地變數。
這把我們的本地變數變成了一個擁有所有 http 模組所提供的公共方法的物件。
Node.js 的 require方法中的檔案查詢策略如下:
由於Node.js中存在4類模組(原生模組和3種檔案模組),儘管require方法極其簡單,但是內部的載入卻是十分複雜的,其載入優先順序也各自不同。如下圖所示:
從檔案模組快取中載入
儘管原生模組與檔案模組的優先順序不同,但是都不會優先於從檔案模組的快取中載入已經存在的模組。
從原生模組載入
原生模組的優先順序僅次於檔案模組快取的優先順序。require方法在解析檔名之後,優先檢查模組是否在原生模組列表中。以http模組為例,儘管在目錄下存在一個http/http.js/http.node/http.json檔案,require("http")都不會從這些檔案中載入,而是從原生模組中載入。
原生模組也有一個快取區,同樣也是優先從快取區載入。如果快取區沒有被載入過,則呼叫原生模組的載入方式進行載入和執行。
從檔案載入
當檔案模組快取中不存在,而且不是原生模組的時候,Node.js會解析require方法傳入的引數,並從檔案系統中載入實際的檔案,載入過程中的包裝和編譯細節在前一節中已經介紹過,這裡我們將詳細描述查詢檔案模組的過程,其中,也有一些細節值得知曉。
require方法接受以下幾種引數的傳遞:
node_modules資料夾用來存放所有已安裝到專案中的包。require()匯入第三方包時,就是從這個目錄中查詢並載入包。
package-lock.json組態檔用來記錄node_modules目錄下的每一個包的下載資訊,例如包的名字、版本號、下載地址等。
注意:不要手動修改node_modules或package-lock.json檔案中的任何程式碼,npm包管理工具會自動維護它們。
在每個.js自定義模組中都有一個module物件,它裡面儲存了和當前模組有關的資訊
每個模組內部,module變數代表當前模組
module變數是一個物件,它的exports屬性(即module.exports)是對外的介面
載入某個模組,其實是載入該模組的module.exports屬性。require()方法用於載入模組。
Node.js 提供一組類似 UNIX(POSIX)標準的檔案操作API。 Node 匯入檔案系統模組(fs)語法如下所示:
var fs = require("fs")
登入後複製
2.1、非同步和同步
Node.js 檔案系統(fs 模組)模組中的方法均有非同步和同步版本,例如讀取檔案內容的函數有非同步的 fs.readFile() 和同步的 fs.readFileSync()。
非同步的方法函數最後一個引數為回撥函數,回撥函數的第一個引數包含了錯誤資訊(error)。
建議大家是用非同步方法,比起同步,非同步方法效能更高,速度更快,而且沒有阻塞。
範例
建立 input.txt 檔案,內容如下:
foo
登入後複製
建立 filereaddemo.js 檔案, 程式碼如下:
const fs=require("fs"); //依賴內建模組fs,用於檔案管理
//非同步讀取檔案students.txt,設定讀取成功時的回撥函數,err表示錯誤資訊,data表示資料
fs.readFile("students.txt",function(err,data){
if(err) throw err;
console.log("非同步:"+data+"");
});
console.log("---------------");
//同步讀取
let data=fs.readFileSync("students.txt");
console.log("同步:"+data+"");
登入後複製
以上程式碼執行結果如下:
接下來,讓我們來具體瞭解下 Node.js 檔案系統的方法。
2.2、獲取檔案資訊
以下為通過非同步模式獲取檔案資訊的語法格式:
fs.stat(path, callback)
登入後複製
引數使用說明如下:
path - 檔案路徑。
callback - 回撥函數,帶有兩個引數如:(err, stats), stats 是 fs.Stats 物件。
fs.stat(path)執行後,會將stats類的範例返回給其回撥函數。可以通過stats類中的提供方法判斷檔案的相關屬性。例如判斷是否為檔案:
const fs=require("fs");
fs.stat("students.txt",(err,stats)=>{
console.log("是檔案嗎?"+stats.isFile());
console.log("是目錄嗎?"+stats.isDirectory());
console.log(stats);
});
登入後複製
結果:
stats類中的方法有:
方法 | 描述 |
---|---|
stats.isFile() | 如果是檔案返回 true,否則返回 false。 |
stats.isDirectory() | 如果是目錄返回 true,否則返回 false。 |
stats.isBlockDevice() | 如果是塊裝置返回 true,否則返回 false。 |
stats.isCharacterDevice() | 如果是字元裝置返回 true,否則返回 false。 |
stats.isSymbolicLink() | 如果是軟連結返回 true,否則返回 false。 |
stats.isFIFO() | 如果是FIFO,返回true,否則返回 false。FIFO是UNIX中的一種特殊型別的命令管道。 |
stats.isSocket() | 如果是 Socket 返回 true,否則返回 false。 |
接下來我們建立 file.js 檔案,程式碼如下所示:
var fs = require("fs");
console.log("準備開啟檔案!");
fs.stat('input.txt', function (err, stats) {
if (err) {
return console.error(err);
}
console.log(stats);
console.log("讀取檔案資訊成功!");
// 檢測檔案型別
console.log("是否為檔案(isFile) ? " + stats.isFile());
console.log("是否為目錄(isDirectory) ? " + stats.isDirectory());
});
登入後複製
以上程式碼執行結果如下:
$ node file.js
準備開啟檔案!
{ dev: 16777220,
mode: 33188,
nlink: 1,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 40333161,
size: 61,
blocks: 8,
atime: Mon Sep 07 2015 17:43:55 GMT+0800 (CST),
mtime: Mon Sep 07 2015 17:22:35 GMT+0800 (CST),
ctime: Mon Sep 07 2015 17:22:35 GMT+0800 (CST) }
讀取檔案資訊成功!
是否為檔案(isFile) ? true
是否為目錄(isDirectory) ? false
登入後複製
2.3、寫入檔案
以下為非同步模式下寫入檔案的語法格式:
fs.writeFile(filename, data[, options], callback)
登入後複製
如果檔案存在,該方法寫入的內容會覆蓋舊的檔案內容。
引數使用說明如下:
path - 檔案路徑。
data - 要寫入檔案的資料,可以是 String(字串) 或 Buffer(流) 物件。
options - 該引數是一個物件,包含 {encoding, mode, flag}。預設編碼為 utf8, 模式為 0666 , flag 為 'w'
callback - 回撥函數,回撥函數只包含錯誤資訊引數(err),在寫入失敗時返回。
接下來我們建立 file.js 檔案,程式碼如下所示:
const fs=require("fs");
fs.writeFile("output1.txt","非同步hello","utf-8",function(err){
if(!err){
console.log("非同步檔案寫入成功!");
}
else{
throw err;
}
});
console.log("---------------");
fs.writeFileSync("output2.txt","同步hello","utf-8");
console.log("同步檔案寫入成功");
登入後複製
以上程式碼執行結果如下:
2.4、刪除檔案
以下為刪除檔案的語法格式:
fs.unlink(path, callback)
登入後複製
引數使用說明如下:
path - 檔案路徑。
callback - 回撥函數,沒有引數。
接下來我們建立 file.js 檔案,程式碼如下所示:
const fs=require("fs");
fs.unlink("output1.txt",function(err){
if(err){
throw err;
}
else{
console.log("非同步刪除檔案成功!");
}
});
console.log("--------------------");
fs.unlinkSync("output2.txt");
console.log("同步刪除檔案成功!");
登入後複製
以上程式碼執行結果如下:
2.5、建立目錄
以下為建立目錄的語法格式:
fs.mkdir(path[, mode], callback)
登入後複製
引數使用說明如下:
path - 檔案路徑。
mode - 設定目錄許可權,預設為 0777。
callback - 回撥函數,沒有引數。
接下來我們建立mkdirfile.js 檔案,程式碼如下所示:
const fs=require("fs");
fs.mkdir("dir1",function(err){
if(err){
throw err;
}
else{
console.log("非同步建立目錄成功!");
}
});
console.log("---------------------");
fs.mkdirSync("dir2");
console.log("同步建立目錄成功!");
登入後複製
以上程式碼執行結果如下:
2.6、讀取目錄
以下為讀取目錄的語法格式:
fs.readdir(path, callback)
登入後複製
引數使用說明如下:
path - 檔案路徑。
callback - 回撥函數,回撥函數帶有兩個引數err, files,err 為錯誤資訊,files 為 目錄下的檔案陣列列表。
接下來我們建立 file.js 檔案,程式碼如下所示:
const fs=require("fs");
fs.readdir("dir1",(err,files)=>{
if(err)
{throw err;}
else{
console.log("非同步獲取目錄下的檔案成功!");
files.forEach(file=>console.log(file));
}
});
console.log("-----------------------");
let files=fs.readdirSync("dir2");
console.log("同步獲取目錄下的檔案成功!");
files.forEach(file=>console.log(file));
登入後複製
以上程式碼執行結果如下:
2.7、刪除目錄
以下為刪除目錄的語法格式:
fs.rmdir(path, callback)
登入後複製
引數使用說明如下:
path - 檔案路徑。
callback - 回撥函數,沒有引數。
接下來我們建立 file.js 檔案,程式碼如下所示:
var fs = require("fs");
console.log("準備刪除目錄 /tmp/test");
fs.rmdir("/tmp/test",function(err){
if (err) {
return console.error(err);
}
console.log("讀取 /tmp 目錄");
fs.readdir("/tmp/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
});
登入後複製
以上程式碼執行結果如下:
$ node file.js
準備刪除目錄 /tmp/test
input.out
output.out
test
test.txt
讀取 /tmp 目錄
……
登入後複製
2.8、檔案模組方法參考手冊
以下為 Node.js 檔案模組相同的方法列表:
方法 | 描述 |
---|---|
fs.rename(oldPath, newPath, callback) | 非同步 rename().回撥函數沒有引數,但可能丟擲異常。 |
fs.ftruncate(fd, len, callback) | 非同步 ftruncate().回撥函數沒有引數,但可能丟擲異常。 |
fs.ftruncateSync(fd, len) | 同步 ftruncate() |
fs.truncate(path, len, callback) | 非同步 truncate().回撥函數沒有引數,但可能丟擲異常。 |
fs.truncateSync(path, len) | 同步 truncate() |
fs.chown(path, uid, gid, callback) | 非同步 chown().回撥函數沒有引數,但可能丟擲異常。 |
fs.chownSync(path, uid, gid) | 同步 chown() |
fs.fchown(fd, uid, gid, callback) | 非同步 fchown().回撥函數沒有引數,但可能丟擲異常。 |
fs.fchownSync(fd, uid, gid) | 同步 fchown() |
fs.lchown(path, uid, gid, callback) | 非同步 lchown().回撥函數沒有引數,但可能丟擲異常。 |
fs.lchownSync(path, uid, gid) | 同步 lchown() |
fs.chmod(path, mode, callback) | 非同步 chmod().回撥函數沒有引數,但可能丟擲異常。 |
fs.chmodSync(path, mode) | 同步 chmod(). |
fs.fchmod(fd, mode, callback) | 非同步 fchmod().回撥函數沒有引數,但可能丟擲異常。 |
fs.fchmodSync(fd, mode) | 同步 fchmod(). |
fs.lchmod(path, mode, callback) | 非同步 lchmod().回撥函數沒有引數,但可能丟擲異常。Only available on Mac OS X. |
fs.lchmodSync(path, mode) | 同步 lchmod(). |
fs.stat(path, callback) | 非同步 stat(). 回撥函數有兩個引數 err, stats,stats 是 fs.Stats 物件。 |
fs.lstat(path, callback) | 非同步 lstat(). 回撥函數有兩個引數 err, stats,stats 是 fs.Stats 物件。 |
fs.fstat(fd, callback) | 非同步 fstat(). 回撥函數有兩個引數 err, stats,stats 是 fs.Stats 物件。 |
fs.statSync(path) | 同步 stat(). 返回 fs.Stats 的範例。 |
fs.lstatSync(path) | 同步 lstat(). 返回 fs.Stats 的範例。 |
fs.fstatSync(fd) | 同步 fstat(). 返回 fs.Stats 的範例。 |
fs.link(srcpath, dstpath, callback) | 非同步 link().回撥函數沒有引數,但可能丟擲異常。 |
fs.linkSync(srcpath, dstpath) | 同步 link(). |
fs.symlink(srcpath, dstpath[, type], callback) | 非同步 symlink().回撥函數沒有引數,但可能丟擲異常。 type 引數可以設定為 'dir', 'file', 或 'junction' (預設為 'file') 。 |
fs.symlinkSync(srcpath, dstpath[, type]) | 同步 symlink(). |
fs.readlink(path, callback) | 非同步 readlink(). 回撥函數有兩個引數 err, linkString。 |
fs.realpath(path[, cache], callback) | 非同步 realpath(). 回撥函數有兩個引數 err, resolvedPath。 |
fs.realpathSync(path[, cache]) | 同步 realpath()。返回絕對路徑。 |
fs.unlink(path, callback) | 非同步 unlink().回撥函數沒有引數,但可能丟擲異常。 |
fs.unlinkSync(path) | 同步 unlink(). |
fs.rmdir(path, callback) | 非同步 rmdir().回撥函數沒有引數,但可能丟擲異常。 |
fs.rmdirSync(path) | 同步 rmdir(). |
fs.mkdir(path[, mode], callback) | S非同步 mkdir(2).回撥函數沒有引數,但可能丟擲異常。 mode defaults to 0777. |
fs.mkdirSync(path[, mode]) | 同步 mkdir(). |
fs.readdir(path, callback) | 非同步 readdir(3). 讀取目錄的內容。 |
fs.readdirSync(path) | 同步 readdir().返回檔案陣列列表。 |
fs.close(fd, callback) | 非同步 close().回撥函數沒有引數,但可能丟擲異常。 |
fs.closeSync(fd) | 同步 close(). |
fs.open(path, flags[, mode], callback) | 非同步開啟檔案。 |
fs.openSync(path, flags[, mode]) | 同步 version of fs.open(). |
fs.utimes(path, atime, mtime, callback) | ? |
fs.utimesSync(path, atime, mtime) | 修改檔案時間戳,檔案通過指定的檔案路徑。 |
fs.futimes(fd, atime, mtime, callback) | ? |
fs.futimesSync(fd, atime, mtime) | 修改檔案時間戳,通過檔案描述符指定。 |
fs.fsync(fd, callback) | 非同步 fsync.回撥函數沒有引數,但可能丟擲異常。 |
fs.fsyncSync(fd) | 同步 fsync. |
fs.write(fd, buffer, offset, length[, position], callback) | 將緩衝區內容寫入到通過檔案描述符指定的檔案。 |
fs.write(fd, data[, position[, encoding]], callback) | 通過檔案描述符 fd 寫入檔案內容。 |
fs.writeSync(fd, buffer, offset, length[, position]) | 同步版的 fs.write()。 |
fs.writeSync(fd, data[, position[, encoding]]) | 同步版的 fs.write(). |
fs.read(fd, buffer, offset, length, position, callback) | 通過檔案描述符 fd 讀取檔案內容。 |
fs.readSync(fd, buffer, offset, length, position) | 同步版的 fs.read. |
fs.readFile(filename[, options], callback) | 非同步讀取檔案內容。 |
fs.readFileSync(filename[, options]) | |
fs.writeFile(filename, data[, options], callback) | 非同步寫入檔案內容。 |
fs.writeFileSync(filename, data[, options]) | 同步版的 fs.writeFile。 |
fs.appendFile(filename, data[, options], callback) | 非同步追加檔案內容。 |
fs.appendFileSync(filename, data[, options]) | The 同步 version of fs.appendFile. |
fs.watchFile(filename[, options], listener) | 檢視檔案的修改。 |
fs.unwatchFile(filename[, listener]) | 停止檢視 filename 的修改。 |
fs.watch(filename[, options][, listener]) | 檢視 filename 的修改,filename 可以是檔案或目錄。返回 fs.FSWatcher 物件。 |
fs.exists(path, callback) | 檢測給定的路徑是否存在。 |
fs.existsSync(path) | 同步版的 fs.exists. |
fs.access(path[, mode], callback) | 測試指定路徑使用者許可權。 |
fs.accessSync(path[, mode]) | 同步版的 fs.access。 |
fs.createReadStream(path[, options]) | 返回ReadStream 物件。 |
fs.createWriteStream(path[, options]) | 返回 WriteStream 物件。 |
fs.symlink(srcpath, dstpath[, type], callback) | 非同步 symlink().回撥函數沒有引數,但可能丟擲異常。 |
更多內容,請檢視官網檔案模組描述:。
3.0、讀取自定義組態檔資料
創立一個 config
目錄並向其中增加一個 config/default.json
檔案。這將是預設組態檔,並將蘊含所有預設環境變數。
在咱們的範例應用程式中它應該是這樣的:
config/default.json
{
"student":{
"name":"tom",
"age":19
}
}
登入後複製
先依賴模組config,
npm i config
登入後複製
咱們將在咱們的應用程式中通過匯入 config
和應用 get
辦法拜訪變數來存取它。
const config=require("config");
console.log(config.get("student.name"));
console.log(config.get("student.age"));
登入後複製
執行結果:
3.1、讀取package.json設定引數
用於新增命令列的環境變數
package.json 可以設定config
指令碼中 (see npm-scripts) package.json 「config」 欄位會被環境變數覆蓋
<name>[@<version>]:<key>
例如,下面的package.json:
程式碼中使用 process.env['npm_package_config_xxxxxx'] 獲取設定的內容
package.json
{
"name": "demo06",
"config": {
"foo": "123456"
},
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"node configtest.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"config": "^3.3.7"
}
}
登入後複製
configtest.js
console.log(process.env.npm_package_config_foo);
登入後複製
直接執行(node configtest.js)結果:
直接在命令列執行 node configtest,會輸出undefined
使用 npm run start,會輸出 123456
npm 設定包的config
npm config set foo = 3000 就可以修改預設的設定內容
然後再執行 npm test 會輸出 3000
3.2、環境變數的設定與讀取
檔案.env
USER_ID="239482"
USER_KEY="foobar"
NODE_ENV="development"
登入後複製
m3.js
npm i dotenv //依賴模組
require("dotenv").config();
console.log(process.env.USER_ID);
登入後複製
輸出結果:
3.3、獲取系統中的環境變數
命令列下操作環境變數
輸入 set 即可檢視。
輸入 「set 變數名」即可。比如想檢視path變數的值,即輸入 set path
注意:所有的在cmd命令列下對環境變數的修改只對當前視窗有效,不是永久性的修改。也就是說當關閉此cmd命令列視窗後,將不再起作用。
永久性修改環境變數的方法有兩種:一種是直接修改登入檔,另一種是通過我的電腦-〉屬性-〉高階,來設定系統的環境變數(檢視詳細)。
輸入 「set 變數名=變數內容」即可。比如將path設定為「d:\nmake.exe」,只要輸入set path="d:\nmake.exe"。
注意,此修改環境變數是指用現在的內容去覆蓋以前的內容,並不是追加。比如當我設定了上面的path路徑之後,如果我再重新輸入set path="c",再次檢視path路徑的時候,其值為「c:」,而不是「d:\nmake.exe」;「c」。
如果想將某一變數設定為空,輸入「set 變數名=」即可。
如「set path=」 那麼檢視path的時候就為空。注意,上面已經說了,只在當前命令列視窗起作用。因此檢視path的時候不要去右擊「我的電腦」——「屬性」........
輸入「set 變數名=%變數名%;變數內容」。(不同於3,那個是覆蓋)。如,為path新增一個新的路徑,輸入「 set path=%path%;d:\nmake.exe」即可將d:\nmake.exe新增到path中,再次執行"set path=%path%;c:",那麼,使用set path語句來檢視的時候,將會有:d:\nmake.exe;c:,而不是像第3步中的只有c:。
假定當前的系統環境變數定義如下,注意JAVA_HOME:
m3.js
console.log(process.env.JAVA_HOME);
登入後複製
輸出:
a,b在系統中已定義好
注意當前的終端是cmd,不是powershell
這裡a輸出123的原因是修改成888後沒有重新啟動電腦。
4.1、根據視訊完成每一個上課範例。
4.2、定義一個模組circle.js,中模組中定義兩個方法一個用於計算圓的周長,一個用於計算圓的面積,再定義一個模組main.js依賴模組circle.js,並呼叫模組中的兩個方法用於計算。
4.3、在組態檔package.json中定義好埠port與主機地址host,建立一個web伺服器,參照設定資訊,實現埠與主機地址的切換功能。
4.4、使用config的方式完成4.3
4.5、使用.env,dotenv的方式完成4.3
4.6、使用系統環境變數完成4.3
更多node相關知識,請存取:!
以上就是一文詳解Node中的模組化、檔案系統與環境變數的詳細內容,更多請關注TW511.COM其它相關文章!