淺析 NodeJs 的幾種文件路徑

2022-01-06 前端教程

點擊上方「前端教程」,選擇「星標」

每天前端開發乾貨第一時間送達!

作者:大果

https://github.com/imsobear/blog/issues/48

一、挖坑 & 掉坑:

緣起一段這樣的代碼:

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

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

/Users/guo/Sites/learn/app/model

/Users/guo/Sites/learn/app/model

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

/Users/guo/Sites/learn/app/model

/Users/guo/Sites/learn/app/model/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');

四、參考連結:

相關焦點

  • Node.js 中的 require 是如何工作的?
    Node 遵循 Commonjs 規範,規範的核心是通過 require 來加載依賴的其他模塊。我們已經常習慣於使用社區提供的各種庫,但對於模塊引用的背後原理知之甚少。這篇文章通過源碼閱讀,淺析在 commonjs 規範中 require 背後的工作原理。require 從哪裡來?
  • Nodejs 基礎:路徑處理模塊 path 總結
    獲取路徑/文件名/擴展名獲取路徑:path.dirname(filepath)獲取文件名:path.basename(filepath)獲取擴展名:path.extname(filepath)獲取所在路徑例子如下:var path = require('path');var filepath = '/tmp/demo/
  • node.js安裝
    配置Node.js環境變量:主要配置npm安裝的全局模塊所在路徑,以及緩存cache的路徑。為了避免全局安裝時,將模塊安裝到c盤,佔用c盤空間。在安裝的文件夾【D:\ProgramData\nodejs】(找到你安裝的路徑)下創建兩個文件夾【node_global】及【node_cache】如下圖:
  • Nodejs 的 C++ 拓展開發
    文件模塊文件模塊則分為兩種方式:2.1 第三方模塊這些模塊以 Nodejs 依賴包的形式存在。例如一些常見的 npm 包 axios、webpack等等。Nodejs require 這一類模塊的話是會去找該模塊項目下面的 package.json 文件,如果 package.json 文件合法,則會解析 main 欄位的那個路徑。
  • Node.js系列二 - Node基礎知識
    JavaScript文件執行如果我們編寫一個js文件,裡面存放JavaScript代碼,如何來執行它呢?/index.js"></script></body></html>瀏覽器執行結果演練二:Node執行如果我們希望把js文件交給node執行:首先電腦上需要安裝Node.js
  • nodejs (一)--什麼是Nodejs 及Node.js 安裝
    --Node.js 不是語言,是讓JavaScript脫離瀏覽器運行在伺服器的一個平臺;--Node.js 採用Google Chrome 瀏覽器的V8引擎,性能較好,同時提供很多系統級的API ,不用考慮瀏覽器外JavaScript的兼容性問題。--Node.js 採用事件驅動,異步編程,為網絡服務而設計。
  • Node.js幾種創建子進程方法
    execFilechild_process.execFile(file[, args][, options][, callback])const { execFile } = require('child_process')execFile('node
  • [nodejs]Node 核心模塊之 child_process
    execFile語法:child_process.execFile(file[, args][, options][, callback])注意:1、與 exec 的不同是,命令的參數不能放在第一個參數,只能作為第二個參數傳遞;2、默認情況下不會衍生 shell,指定的可執行 file 直接作為新進程衍生,使其比 child_process.exec()稍微更高效3、file 是要運行的可執行文件的名稱或路徑
  • 結合源碼分析 Node.js 模塊加載與運行原理
    JavaScript 模塊,這是最常見的,我們開發的時候一般都寫的是 JavaScript 模塊JSON 模塊,這個很簡單,就是一個 JSON 文件C/C++ 擴展模塊,使用 C/C++ 編寫,編譯之後後綴名為 .node本篇文章中,我們會一一涉及到上述幾種模塊的加載、運行原理。2.
  • Node.js學習筆記第一天
    01-導入node模塊使用流程// node.js中將不同功能的代碼放在不同的js文件中,也叫模塊化,核心模塊會隨著安裝node.js時一併安裝// 1. 02- fs模塊基本使用2.1 readFile 讀取文件數據// 1.導入模塊const fs = require('fs');// 2.讀取文件// fs.readFile('文件路徑', options, 回調函數(err, data
  • Node 中文周刊 #15 - 提高 Node.js 性能的 7 種方法!
    上周 Ayooluwa Isaiah 為大家帶來了 7 種性能優化方法,快來看看吧!編輯:辛寶 Otto、gaao🔥 本周熱門在 Node 中使用校驗工具 — 如果我們想在 web 應用校驗中發送的數據,而且數據十分複雜。
  • JS 實現網頁截屏五種方法
    await page.setViewport({ // 設置視窗大小    width: 600,    height: 800    });    await page.goto('https://example.com'); // 打開頁面    await page.screenshot({path: 'example.png'}); // path: 截屏文件保存路徑
  • Node.js基礎
    script1.jsscript2.js"scripts": { "script1": "node script1.js", "script2": "node script2.js"}如果是並行執行(即同時的平行執行),可以使用
  • Node.js安裝教程
    /Win8/Win10[Node.js15.11.0下載連結]:https://wwa.lanzoui.com/node15[Node.js14.16.0下載連結]:https://wwa.lanzoui.com/node14Node.js是一個基於Chrome V8引擎的JavaScript運行環境,讓JavaScript運行在服務端的開發平臺,使JavaScript
  • Windows7系統Node.js安裝及環境配置
    一、教程安裝環境1、電腦系統:Windows 7(64位)2、Node.js版本:node-v8.10.0-x64.msi二、下載Node.js步驟1、下載對應你系統的Node.js版本【地址見文末】(紅色框選位置為版本選擇合適自己系統的版本下載)
  • Node.js 診斷指南 第二彈
    我們的作業系統內核有提供了一種機制來讓我在應用 crash 的時候生成 core 文件,通過 core 文件開發者就可以分析和恢復場景。目前來說有 3 種方式可以幫助我們產生 core 文件。首先我們需要調整 ulimit -c unlimited 來幫助我們修改 OS 的默認限制(如果不這樣設置的話,默認情況下 core file 的 size 限制是 0,即不能產生)。
  • Node.js的安裝和環境配置(2020)
    四,Node.js的配置主要配置npm全局模塊的安裝路徑以及緩存cache的路徑。如果不配置的話,默認【npm install 模塊名 -g】是安裝到【C:\Users\用戶名\AppData\Roaming\npm】路徑中,而此處希望將全局模塊和緩存路徑放到Node.js的安裝目錄下【D:\Soft\NodeJs】。
  • 【新手向】Vue.js + Node.js(koa) 合體指南
    vue/webpack.config.js"  }}編寫 webpack.config.js本文的重點不是 webpack 的配置方式,因此這裡比較簡略,不詳細講述每個配置項的含義webpack.config.js 本質上是一個返回 JSON 的配置文件,我們會用到其中的幾個 key。
  • Node.js 模塊系統源碼探微
    module.exports = { add, minus}通過全局 require 函數引用模塊,可傳入模塊名稱、相對路徑或者絕對路徑,當模塊文件後綴為 js / json / node 時,可省略後綴,如下代碼所示:// 引用模塊const { add, minus } = require('.
  • Node.js 模塊化你所需要知道的事
    我們知道在Node.js中,文件即模塊,剛剛提到了模塊可以是.js、.json或者.node文件,通過引用它們,可以獲取工具函數、變量、配置等等,但是它的具體結構是怎樣呢?Node.js允許我們用多種方式來引用模塊,比如相對路徑、絕對路徑、預置路徑(馬上會解釋),假設我們需要引用一個叫做find-me的模塊,require如何幫助我們找到這個模塊呢?