千家信息网

nodejs中的__dirname和__filename变量怎么使用

发表于:2024-11-17 作者:千家信息网编辑
千家信息网最后更新 2024年11月17日,本篇内容介绍了"nodejs中的__dirname和__filename变量怎么使用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希
千家信息网最后更新 2024年11月17日nodejs中的__dirname和__filename变量怎么使用

本篇内容介绍了"nodejs中的__dirname和__filename变量怎么使用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1.问题背景

写这篇文章的背景在于今天遇到一个神奇的报错,一起来看下

// index.jsconsole.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.jsconsole.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 modulesconsole.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变量怎么使用"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0