概述
本篇文章带大家了解一下node中你不知道的__dirname和__filename变量,有一定的参考价值,希望对大家有所帮助!
1.问题背景
写这篇文章的背景在于今天遇到一个神奇的报错,一起来看下
// index.js
console.log(__filename);
// 执行 node index.js
// ReferenceError: __filename is not defined in ES module scope
登录后复制
在node环境访问全局变量__filename居然报错,什么原因呢??于是开始了一路的探索,最终找到问题的根源。
2. node模块机制
我们知道早期node.js的模块标准采用commonjs模块规范,然而在nodejs版本v13.2.0中,开始支持ES Modules模块规范,我们可以有以下几种方式在node中使用ES Modules模块
- 将文件后缀命名为.mjs
- package.json 新增 "type": "module"字段
当我们在node中使用ES Modules贵方,以下全局对象和变量将不可用
- require
- module.exports
- exports
- __filename
- __dirname
- NODE_PATH
3. 为什么采用commonjs模块化可以使用__filename和__dirname?
这个问题,主要归结于commonjs模块下nodejs的运行机制,很多人可能认为__filename就是node环境中的全局变量,当出现这个问题的时候,我们才意识到,这两个不是Node中真正的全局变量。
看一段简单的js代码
(function(){
console.log(arguments) // [1,2,3]
})(1,2,3)
登录后复制
arguments在函数内部可以拿到调用函数时传入的参数。
我们在node commonjs模块中执行以下代码
// index.js
console.log(arguments);
[Arguments] {
'0': {},
'1': [Function: require] {
resolve: [Function: resolve] { paths: [Function: paths] },
main: Module {
id: '.',
path: 'E:\nodeProjectStorehouse\nodeStudyFromBook',
exports: {},
filename: 'E:\nodeProjectStorehouse\nodeStudyFromBook\cc.cjs',
loaded: false,
children: [],
paths: [Array]
},
extensions: [Object: null prototype] {
'.js': [Function (anonymous)],
'.json': [Function (anonymous)],
'.node': [Function (anonymous)]
},
cache: [Object: null prototype] {
'E:\nodeProjectStorehouse\nodeStudyFromBook\cc.cjs': [Module]
}
},
'2': Module {
id: '.',
path: 'E:\nodeProjectStorehouse\nodeStudyFromBook',
exports: {},
filename: 'E:\nodeProjectStorehouse\nodeStudyFromBook\cc.cjs',
loaded: false,
children: [],
paths: [
'E:\nodeProjectStorehouse\nodeStudyFromBook\node_modules',
'E:\nodeProjectStorehouse\node_modules',
'E:\node_modules'
]
},
'3': 'E:\nodeProjectStorehouse\nodeStudyFromBook\cc.cjs',
'4': 'E:\nodeProjectStorehouse\nodeStudyFromBook'
登录后复制
我们可以看到,arguments有5个参数,这5个参数就是exports, require, module, __filename, __dirname
到这里我们就清楚的知道,__filename不是全局变量,而是外层传入的参数而已
既然这样,我们在ES Modules模块下,访问arguments看下结果是什么?
// index.js ES modules
console.log(arguments);
// ReferenceError: arguments is not defined
登录后复制
4. ES Modules下如何使用__filename和__dirname?
node官方文档建议使用import.meta.url变相的提供
// import.meta.url 返回模块的绝对的 `file:` URL。
// url模块中fileURLToPath()函数,返回完全解析的特定于平台的 Node.js 文件路径
// path模块中dirname()函数,返回路径的目录路径
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
登录后复制
最后
以上就是复杂方盒为你收集整理的浅析nodejs中的__dirname和__filename变量的全部内容,希望文章能够帮你解决浅析nodejs中的__dirname和__filename变量所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复