回覆列表
  • 1 # lanfengz3

    一、挖坑 & 掉坑:

    緣起一段這樣的程式碼:

    fs.readFile("./docs/use.md", function (err, buffer) {

    if (err) {

    return console.log("error: ", err);

    }

    console.log("OK");

    });

    本地執行時一切 OK,線上部署時卻死活找不到 ./docs/use.md 這個檔案,後來才發現是因為線上啟動應用時不是從當前目錄啟動了,不過為什麼啟動指令碼的位置也會影響這個路徑呢,且往下看。

    二、填坑:

    Node 中的檔案路徑大概有 __dirname, __filename, process.cwd(), ./ 或者 ../,前三個都是絕對路徑,為了便於比較,./ 和 ../ 我們透過 path.resolve(‘./’)來轉換為絕對路徑。

    先看一個簡單的栗子:

    假如我們有這樣的檔案結構:

    app/

    -lib/

    -common.js

    -model

    -task.js

    -test.js

    在 task.js 裡編寫如下的程式碼:

    var path = require("path");console.log(__dirname);console.log(__filename);console.log(process.cwd());console.log(path.resolve("./"));

    在 model 目錄下執行 node task.js 得到的輸出是:

    /Users/guo/Sites/learn/app/model.js/Users/guo/Sites/learn/app/model.js/task.js/Users/guo/Sites/learn/app/model.js/Users/guo/Sites/learn/app/model.js

    然後在 app 目錄下執行 node model/task.js,得到的輸出是:

    /Users/guo/Sites/learn/app/model.js/Users/guo/Sites/learn/app/model.js/task.js/Users/guo/Sites/learn/app

    /Users/guo/Sites/learn/app

    那麼,不好意思不是問題來了~T_T,我們可以得出一些膚淺的結論了:

    __dirname: 總是返回被執行的 js 所在資料夾的絕對路徑

    __filename: 總是返回被執行的 js 的絕對路徑

    process.cwd(): 總是返回執行 node 命令時所在的資料夾的絕對路徑

    ./: 跟 process.cwd() 一樣、一樣、一樣的嗎?

    我明明記得在 require(‘../lib/common’) 裡一直都是各種相對路徑寫,也沒見報什麼錯啊,我們還在再來個栗子吧,還是上面的結構,’model/task.js’ 裡的程式碼改成:

    var fs = require("fs");var common = require("../lib/common");

    fs.readFile("../lib/common.js", function (err, data) { if (err) return console.log(err);

    console.log(data);

    });

    在 model 目錄下執行 node task.js,一切 Ok,沒有報錯。然後在 app 目錄下執行 node model/task.js,然後很果斷滴報錯了:

    那麼這下問題真的都是來了,按照上面的理論,在 app 下執行時,../lib/common.js 會被轉成 /Users/guo/Sites/learn/lib/common.js,這個路徑顯然是不存在的,但是從執行結果可以看出 require(‘../lib/common’) 是 OK 的,只是 readFile 時報錯了。

    那麼關於 ./ 正確的結論是:

    在 require() 中使用是跟 __dirname 的效果相同,不會因為啟動指令碼的目錄不一樣而改變,在其他情況下跟 process.cwd() 效果相同,是相對於啟動指令碼所在目錄的路徑。

    三、總結:

    只有在 require() 時才使用相對路徑(./, ../) 的寫法,其他地方一律使用絕對路徑,如下:

    // 當前目錄下

    path.dirname(__filename) + ‘/test.js’;

    // 相鄰目錄下

    path.resolve(__dirname, ‘../lib/common.js’);

    四、參考連結:

    What is the difference between __dirname and ./ in node.js

    nodejs API

    以上:smile:。

  • 中秋節和大豐收的關聯?
  • 諸葛亮都害死了誰?