本篇文章跟大家介紹一下Nodejs中Process、Path、File System模組常用 API。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
相關推薦:《nodejs 教學》
在日常使用Node 進行開發的時候,會使用到一些檔案系統、路徑操作等基礎API,這裡整理一下,方便大家理解直接使用。
這裡只介紹最常用的那些,不是所有哈,想要看更全的,直接看官方文件就 OK。
盡量不廢話,多上程式碼。
先介紹 process 模組,它提供了目前 Node 程序相關的全域環境資訊。在後面的 API 中被用到。
// 内置模块,直接使用 const process = require('process');
#這是一個函數,傳回目前Node 程式執行的目錄,舉例一個常見的場景:
一個Node 模組A
透過NPM 發布,在專案B
中使用了模組A
。在 A
中需要操作 B
專案下的檔案時,就可以用 process.cwd()
來取得 B
專案的路徑。
const cwd = process.cwd(); // 输出:/Users/xiaolian/Code/node-api-test
在終端機透過Node 執行指令的時候,透過process.argv
可以取得傳入的命令列參數,傳回值是一個陣列:
所以,我們只要從process.argv[2]
開始取得就好了。 一般都是這樣用:
const args = process.argv.slice(2);
直接取得我們想要的參數。
返回一個對象,儲存當前環境相關的所有信息,一般很少直接用到。
一般我們會在 process.env
上掛載一些變數來標識目前的環境。例如最常見的用 process.env.NODE_ENV
區分 development
和 production
。在 vue-cli
的原始碼中也常會看到 process.env.VUE_CLI_DEBUG
標識目前是不是一 DEBUG
模式。
這裡提一個webpack 的插件DefinePlugin,在日常的建置流程中,我們常常會透過這個外掛程式來注入不同的全域變量,從而執行不同的建置流程,並且程式碼中的process.env.xxx
會被替換成具體的值,在Terser 壓縮階段會將deadCode 移除,優化程式碼體積。
這個用的不多,回傳目前系統信息,枚舉值如下:
console.log(process.platform); // 'aix' // 'darwin' - macOS // 'freebsd' // 'linux' - linux // 'openbsd' // 'sunos' // 'win32' - windows
// 内置模块,直接使用 const path = require('path');
Node 中幾乎路徑相關的操作都會使用這個模組。
這裡就說5 個最常用的:
path.join
作用是將傳入的多個路徑拼成一個完整的路徑。
const dPath = path.join('template', 'aaa', 'bbb', 'ccc', 'd.js'); // 输出: template/aaa/bbb/ccc/d.js
來看一個非常常見的場景,我們需要取得目前專案的package.json 文件,就可以這樣取得它的路徑:
const pkgPath = path.join(process.cwd(), './package.json'); // 输出: /Users/xiaolian/Code/node-api-test/package.json
path.join
可以傳入任一路徑,例如:
['package.json', 'README.md'].forEach(fileName => { const templateFilePath = path.join(process.cwd(), 'template', fileName); console.log(templateFilePath); }); // 输出: /Users/xiaolian/Code/node-api-test/template/package.json // 输出: /Users/xiaolian/Code/node-api-test/template/README.md
path.resovle
和 path.join
的差異在於它的作用是將傳入的多個路徑和目前執行路徑拼接成一個完整的絕對路徑。
假設我現在index.js
在scripts
目錄下,然後我在根目錄下執行node scripts/index.js
,它的程式碼如下:
const dPath = path.resolve('aaa', 'bbb', 'ccc', 'd.js'); // 输出: /Users/xiaolian/Code/node-api-test/aaa/bbb/ccc/d.js
一般情況下,當path.resolve
的第一個參數為./
時,可以直接理解和path. join(processs.cwd(), '')
表現一致。
#path.basename
傳回指定path
最後一個路徑名,其中第二個參數ext
可選,表示檔案副檔名。例如:
console.log(path.basename('scripts/index.js')); // index.js console.log(path.basename('scripts/index.js', '.js')); // 匹配到 .js,返回 index console.log(path.basename('scripts/index.js', '.json')); // 没匹配到,返回 index.js
和path.basename
對應,傳回指定path
最後一個路徑名之前的路徑。如:
console.log(path.basename('scripts/index.js')); // scripts console.log(path.basename('scripts/hook/index.js')); // scripts/hook
和 path.basename
对应,返回指定 path
最后一个路径名的文件扩展名(含小数点 .
)。比如:
console.log(path.basename('scripts/index.js')); // .js console.log(path.basename('README.md')); // .md
最后再来对比一下各个路径相关的 API 的区别。
项目 A
的目录结构如下:
├── scripts │ └── index.js ├── src │ └── index.js ├── package.json ├── README.md
scripts/index.js
的代码如下:
const path = require('path'); console.log(path.join('package.json')); console.log(path.resolve('package.json')); console.log(path.join('src', 'index.js')); console.log(path.resolve('src', 'index.js')); console.log(path.join(process.cwd(), 'package.json')); console.log(path.resolve('./', 'package.json')); console.log(__filename); console.log(__dirname);
然后,我们在项目 A
的跟目录下执行 node scripts/index.js
,结果如下:
-> node scripts/index.js package.json /Users/xiaolian/Code/A/package.json src/index.js /Users/xiaolian/Code/A/src/index.js /Users/xiaolian/Code/A/package.json /Users/xiaolian/Code/A/package.json /Users/xiaolian/Code/A/scripts/index.js /Users/xiaolian/Code/A/scripts
品,仔细品,它们有什么区别。
个人而言,一般还是习惯用 path.join(process.cwd(), 'xxx')
。
// 内置模块,直接使用 const fs = require('fs');
文件系统相关操作的模块,除了 fs
之外,我们还经常用到 fs-extra
,后面会介绍。
这个模块在平时的 Node 开发中会被大量使用,这里简单列几个,其它的还是看文档哈:nodejs.org/dist/latest…
fs
模块的 API 默认都是异步回调的形式,如果你想使用同步的方法,有两种解决方法:
xxxSync
,也就是在 API 的后面加一个 Sync
后缀,它就是一个同步方法了(具体还是需要查文档哈,是否有提供同步 API)fs.stat()
返回一个文件或者目录的信息。
const fs = require('fs'); fs.stat('a.js', function(err, stats) { console.log(stats); });
其中包含的参数有很多,介绍几个比较常用的:
export interface StatsBase<T> { isFile(): boolean; // 判断是否是一个文件 isDirectory(): boolean; // 判断是否一个目录 size: T; // 大小(字节数) atime: Date; // 访问时间 mtime: Date; // 上次文件内容修改时间 ctime: Date; // 上次文件状态改变时间 birthtime: Date; // 创建时间 }
一般我们会使用 fs.stat
来取文件的大小,做一些判断逻辑,比如发布的时候可以检测文件大小是否符合规范。在 CLI 中,经常需要获取一个路径下的所有文件,这时候也需要使用 fs.stat
来判断是目录还是文件,如果是目录则继续递归。当然,现在也有更方便的 API 可以完成这个工作。
const fs = require('fs'); try { const stats = fs.statSync('a.js'); } catch(e) {}
fs.readdir(path)
获取 path
目录下的文件和目录,返回值为一个包含 file
和 directory
的数组。
假设当前目录为:
. ├── a │ ├── a.js │ └── b │ └── b.js ├── index.js └── package.json
执行以下代码:
const fs = require('fs'); fs.readdir(process.cwd(), function (error, files) { if (!error) { console.log(files); } });
返回值为:
[ 'a', 'index.js', 'package.json' ]
可以看到这里只返回了根目录下的文件和目录,并没有去深度遍历。所以如果需要获取所有文件名,就需要自己实现递归。
const fs = require('fs'); try { const dirs = fs.readdirSync(process.cwd()); } catch(e) {}
文件读取的 API,通过 fs.readFile
可以获取指定 path
的文件内容。
入参如下:
encoding
和 flag
,也可以直接传如 encoding
字符串使用方法如下:
const fs = require('fs'); const path = require('path'); fs.readFile(path.join(process.cwd(), 'package.json'), 'utf-8', function ( error, content ) { if (!error) { console.log(content); } });
如果没传 encoding
,则其默认值为 null
,此时返回的文件内容为 Buffer
格式。
const fs = require('fs'); try { fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'); } catch(e) {}
对应着读文件 readFile
,fs
也提供了写文件的 API writeFile
,接收四个参数:
encoding
和 flag
,也可以直接传如 encoding
字符串使用方法如下:
const fs = require('fs'); const path = require('path'); fs.writeFile( path.join(process.cwd(), 'result.js'), 'console.log("Hello World")', function (error, content) { console.log(error); } );
const fs = require('fs'); const path = require('path'); try { fs.writeFileSync( path.join(process.cwd(), 'result.js'), 'console.log("Hello World")', 'utf-8' ); } catch (e) {}
本文主要是总结了一下在开发 Node 时常用的一些 API,后续的文章会带来 Node 常用的一些三方包。
更多编程相关知识,请访问:编程视频!!
以上是詳解Node.js中Process、Path、File System模組常用 API的詳細內容。更多資訊請關注PHP中文網其他相關文章!