关于nodejs的启动路径和当前路径问题
本文由 小茗同学 发表于 2017-06-16 浏览(8978)
最后修改 2017-07-27 标签:nodejs

前言

本文对nodejs的工作目录和当前目录问题进行好好的测试验证。

【20160622更新】:本文没什么看的价值,水文一篇,特此提醒!

验证

如下,建立文件D:\myjs\test.js如下:

const fs = require('fs');
const path = require('path');
const {exec} = require('child_process');

console.log('当前工作路径:' + process.cwd());
console.log('当前JS所在路径:' + __dirname);

var folderName = 'myfolder_';
fs.mkdirSync(folderName + '111');
fs.mkdirSync(path.resolve(folderName + '222'));
fs.mkdirSync(path.resolve(process.cwd(), folderName + '333'));
fs.mkdirSync(path.resolve(__dirname, folderName + '444'));

exec('echo %cd%', (error, stdout, stderr) => console.log('子进程当前目录:' + stdout));

同目录执行

假如我们直接在js所在目录执行node test.js,没啥好说的,结果肯定如下:

D:\myjs>node test.js
当前工作路径:D:\myjs
当前JS所在路径:D:\myjs
子进程当前目录:D:\myjs

同时,同目录下建立了如下4个文件夹:

非同目录执行

如果我们到E:\test下去执行node D:\myjs\test.js呢?

E:\test>node D:\myjs\test.js
当前工作路径:E:\test
当前JS所在路径:D:\myjs
子进程当前目录:E:\test

第三种情况

E:\bat\test.bat中写入:

@echo off
node D:\myjs\test.js

然后在E:\call执行call E:\bat\test.bat

E:\call>call E:\bat\test.bat
当前工作路径:E:\call
当前JS所在路径:D:\myjs
子进程当前目录:E:\call

第四种情况

假设bat和js文件放在同一目录,bat路径确定,js路径未知,执行环境在另外一目录:

D:\myjs\test.bat

@echo off
echo %cd%
echo %~dpf0
node %~dp0%test.js

我们在E:\exe下执行D:\myjs\test.bat

不用说,一切正常:

E:\exe>D:\myjs\test.bat
E:\exe
D:\myjs\test.bat
当前工作路径:E:\exe
当前JS所在路径:D:\myjs
子进程当前目录:E:\exe

第五种情况

这种情况才是我研究的原因。

将批处理打包成exe,我用了一个叫Bat To Exe Converter的工具,将第四种情况中的test.battest.js打包成exe后放在E:\exe\test.exe执行效果:

E:\exe>test.exe
C:\Users\Administrator\AppData\Local\Temp\F4AA.tmp
E:\exe\test.exe
module.js:471
	throw err;
	^

Error: Cannot find module 'E:\exe\test.js'

可以看到,这个工具生成的exe会把bat文件和js文件解压到某个临时目录,但是却把%cd%%~dpf0和第四种情况完全对调了一下,它的本意是好的,把工作路径设置到bat所在目录减少相对路径的处理,但是我所希望的恰恰是放到exe所在目录,经过一番尝试,改为如下:

@echo off
set tempPath=%cd%
%~d0
cd %~dp0
node %tempPath%\test.js

执行结果:

E:\exe>test.exe
当前工作路径:E:\exe
当前JS所在路径:C:\Users\Administrator\AppData\Local\Temp\ED44.tmp
子进程当前目录:E:\exe

执行结果和第四种情况完全一致。

总结

我屮艸芔茻,写的什么玩意儿,本来是想验证folderNamepath.resolve(folderName)在某些情况不一致的问题的,结果验证了半天发现是之前不知道怎么的代码搞错了,白写这一篇文章了,哎,懒得删了!

本文没什么看的价值,特此提醒!