【nodejs】“__dirname is not defined”错误修复

▒ 目录 ▒

    • 🛫 问题
      • 描述
      • 环境
    • 1️⃣ 原理
      • CommonJS vs ESM
      • 错误原因
    • 2️⃣ 禁用 ESM 模式并改用 CommonJS
      • 方案一:项目
      • 方案二:单文件
    • 3️⃣ 在 ESM 模式下自实现__dirname
    • 📖 参考资料

🛫 问题

描述

从网上找了一份代码,其中包含了__dirname变量的使用,结果运行的时候报错:__dirname is not defined

环境

版本号描述
文章日期2023-06-
操作系统Ubuntu 20.04.4 LTSCSDN开发云
node -vv16.17.0npm -v (8.15.0)
Cloud IDE1.71.0
操作系统Win11 - 21H2 - 22000.1335
Python3.7.1
frida.exe15.0.18

1️⃣ 原理

CommonJS vs ESM

讨论__dirname报错,首先要分清楚CommonJS 和 ESM的区别。
CommonJS 和 ESM(ECMAScript Modules) 都是 JavaScript 模块系统的规范,用于组织和管理代码。它们之间有一些区别,下面简要介绍一下:

特点CommonJSESM
加载方式同步加载异步加载
导出/引入关键字module.exports 和 require()export 和 import
支持环境Node.js 默认支持现代浏览器和最新版本的 Node.js 支持
应用范围主要用于服务器端开发,如 Node.js在浏览器端和 Node.js 中有广泛应用,是未来趋势

错误原因

在 CommonJS 模式下,__dirname 是包含当前文件目录变量。 许多Node.js项目都依赖于此变量。
但不能在 ESM 模式下使用(ESM模式不提供 __dirname 变量)。 您有两种选择:

  • 禁用 ESM 模式并改用 CommonJS
  • 聚填充__dirname

2️⃣ 禁用 ESM 模式并改用 CommonJS

在 JavaScript 中,通常文件扩展名 “.js” 用于表示普通的 JavaScript 文件,
而 “.mjs” 用于表示 ECMAScript 模块(ESM)文件。这两种文件扩展名的区别在于它们所代表的 JavaScript 模块类型。

  • .js 文件:通常用来表示普通的 JavaScript 文件,其中可能包含常规的 JavaScript 代码,采用 CommonJS 或其他模块加载方案。
  • .mjs 文件:表示 ECMAScript 模块,这种文件中的代码采用了 ECMAScript Modules(ESM)规范,即使用 “import” 和 “export” 关键字来定义模块。

要使用 “.mjs” 文件,您需要确保在 Node.js 中启用了对 ECMAScript 模块的支持。您可以通过以下几种方式之一实现:

方案一:项目

Node.js 项目中的 package.json 文件是一个用于描述项目信息、依赖关系和脚本命令的 JSON 文件。它位于项目根目录下,是 Node.js 项目的重要配置文件之一。
在 Node.js 项目中的 package.json 文件中,“type” 字段不要设置为 “module”,以明确告知 Node.js 不使用 ESM 规范(或者直接删除)
在这里插入图片描述

方案二:单文件

对于单文件运行node,即不包含 package.json 文件的情况。node是根据文件后缀判断运行模式的。
我们确保文件后缀是.js,而不是.mjs即可使用__dirname。

3️⃣ 在 ESM 模式下自实现__dirname

在 ECMAScript 模块(ESM)中,与 CommonJS 不同,没有像 __dirname 这样的内置变量来表示当前模块的目录路径。不过,您可以通过一些方法来模拟实现类似的功能。

一种常见的方法是使用 import.meta.url 属性来获取当前模块的 URL,然后从中提取出目录路径。下面是一个示例代码,演示如何在 ESM 模式下自实现类似 __dirname 的功能:

import path from 'path';
import { fileURLToPath } from 'url';const __dirname = path.dirname(fileURLToPath(import.meta.url));

在这个示例中,我们首先导入了 Node.js 中的 fileURLToPath 和 dirname 函数,然后使用 import.meta.url 获取当前模块的 URL。接着,通过 fileURLToPath 将 URL 转换为文件路径,并最终通过 dirname 获取该文件路径的目录部分,从而模拟实现了类似 __dirname 的功能。
请注意,这种方法依赖于 Node.js 提供的 url 和 path 模块,确保您的项目中已安装这些模块。这样,您就可以在 ESM 模式下获取当前模块的目录路径,类似于 CommonJS 中的 __dirname 变量。

📖 参考资料

  • How To Fix “__dirname is not defined” Error in Node.js https://masteringjs.io/tutorials/node/__dirname-is-not-defined

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/725836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

x86 Ubuntu上编译eudev给龙芯loongarch64架构主机使用

1、下载eudev库eudev-master.zip,链接:eudev库官方地址 2、下载龙芯的交叉编译工具:loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.2.tar.xz,链接:龙芯交叉编译官方地址 3、交叉编译器环境搭建 (1)、…

.bat文件与python

.bat文件通常使用文本编辑器(如记事本)来创建和编辑。你只需要在文本文件中编写一系列命令和指令,然后将文件保存为.bat扩展名即可。这样,Windows操作系统就可以识别它为批处理脚本文件。 .bat文件是由Windows操作系统识别的批处理…

InfluxDB SHOW SERIES语句按照什么顺序返回?

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 文章目录 引言样例SHOW SERIES比较原理结论结束语 引言 influxdb的计算引擎为了做到自底而上的…

嵌入式 Linux 开发的基本概念 及 学习路线

原文链接:https://www.cnblogs.com/DSCC2020/p/13787321.html 1.嵌入式 Linux 开发的基本概念 1.1嵌入式 Linux 的组成 嵌入式 Linux 系统,就相当于一套完整的 PC 软件系统,如下图所示: 1.2嵌入式 Linux 的日常开发流程 Bootloa…

IDEA稀奇古怪问题的解决方案

idea在电脑死机重启后,启动项目报错 尝试了各种办法,重新导入项目,删除.idea文件重新导入,把本地代码删除重新pull下来再次导入,均无法解决。而且代码在eclipse中可以正常启动,遂排除代码和网络环境原因。…

探索c++——了解c++的魅力

前言:c是一门既面向对象又面向过程的语言。 不同于java纯粹的面向对象和c纯粹的面向过程。 造成c该特性的原因是c是由本贾尼大佬在c的基础上增添语法创建出来的一门新的语言。 它既兼容了c, 身具面向过程的特性。 又有本身的面向对象的特性。 面向对象和…

软考高级:UML 图 结构图、行为图和交互图 概念和题目

作者:明明如月学长, CSDN 博客专家,大厂高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

在 Docker 环境下安装 OpenWrt

在 Docker 环境下安装 OpenWrt 是一种方便且易于管理的方式,它允许您在不需要物理设备的情况下运行 OpenWrt。以下是在 Docker 中安装 OpenWrt 的步骤: 首先,您需要安装 Docker。具体安装方法可以参考 Docker 官方文档。在安装完成后&#xf…

Vue3+Vue Router使用<transition>过渡动画实现左右分栏后台布局

摘要 利用Vue3及其配套的Vue Router实现后台管理系统中的页面过渡动画。文章首先简要介绍了Vue3的特性和Vue Router的基本用法,利用Vue3提供的组件以及Vue Router的路由钩子函数来实现页面过渡效果。 代码结构 在 components 里有4个组件,其中 Layout…

笔记本上使用usb蓝牙适配器

注意 必须先禁用笔记本上原来的蓝牙功能 禁用笔记本原来的蓝牙功能 使用usb蓝牙适配器

vue实现base64格式转换为图片

找了很多&#xff0c;但是都不太好用&#xff0c;打算自己总结一个保姆级教学&#xff0c;无需动脑&#xff0c;电脑有电就能实现 在HTML部分&#xff0c;我们需要一个标签来放置图片 <template><div><img :src"imageSrc" alt"未获取到图片&qu…

LVS集群---二

1.LVS工作模式和相关命令 1.1LVS集群工作模式 - lvs-nat&#xff1a;修改请求报文的目标IP,多目标IP的DNAT- lvs-dr&#xff1a;操纵封装新的MAC地址&#xff08;直接路由&#xff09;- lvs-tun&#xff1a;隧道模式 1.1.1 LVS的NAT模式 lvs-nat&#xff1a;本质是多目标IP的…

openssl3.2 - exp - 产生随机数

文章目录 openssl3.2 - exp - 产生随机数概述笔记END openssl3.2 - exp - 产生随机数 概述 要用到openssl产生的随机数, 查了资料. 如果用命令行产生随机数, 如下: openssl rand -hex -num 6 48bfd3a64f54单步跟进去, 看到主要就是调用了一个RAND_bytes(), 没其他了. 官方说…

在Linux/Ubuntu/Debian 上打开 RAR 文件

要在 Ubuntu 上打开 RAR 文件&#xff0c;你需要使用支持 RAR 压缩格式的实用程序。 以下是你可以使用的两种流行工具&#xff1a; 1. 安装解压&#xff1a; 打开终端。 使用以下命令安装“unrar”实用程序&#xff1a; sudo apt-get update sudo apt-get install unrar安装后…

人工智能在信息系统安全中的运用

一、 概述 对于企业和消费者来讲&#xff0c;人工智能是非常有用的工具&#xff0c;那又该如何使用人工智能技术来保护敏感信息?通过快速处理数据并预测分析&#xff0c;AI可以完成从自动化系统到保护信息的所有工作。尽管有些黑客利用技术手段来达到自己的目的&#xff0c;但…

在C#中使用Linq

在C#中使用Linq 前言一、基本查询操作二、高级查询操作三、数据库查询四、文件和 XML 查询五、总结 前言 LINQ&#xff08;Language Integrated Query&#xff09;是 C# 中一种强大的查询语言集成特性&#xff0c;它使得在编程语言级别对数据进行查询和操作变得更加简单和直观…

华为数通方向HCIP-DataCom H12-821题库(多选题:101-120)

第101题 下面关于Network-Summary-LSA描述正确的是 A、Network-Summary-LSA中的Metric被设置成从该ABR到达目的网段的开销值 B、Network-Summary-LSA中 的Netmask被设置成目的网段的网络掩码 C、Network-Summary-LSA中的Link State ID被设置成目的网络的IP地址 D、Network-Sum…

【AI视野·今日Robot 机器人论文速览 第八十三期】Wed, 6 Mar 2024

AI视野今日CS.Robotics 机器人学论文速览 Wed, 6 Mar 2024 Totally 30 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;SpaceHopper,外星探索多功能三足机器人 (from Robotic Systems Lab, ETH Zurich) Daily Robotics Papers A Safety-Criti…

JavaSE——基础小项目-模拟ATM系统(项目主要目标、技术选型、架构搭建、具体实现、完整代码注释)

目录 项目主要目标 技术选型 面向对象编程 使用集合容器 程序流程控制 使用常见API 系统架构搭建与欢迎页设计 Account ATM Test 用户开户功能实现 录入账户名称与性别 录入账户密码与取现额度 生成新卡号 存入账户 登录功能实现 登录后操作实现 退出账户 存…

每日学习总结20240306

每日总结 20240306 1. 断言测试判断 #include <iostream> #include <assert.h> #include <cassert> #include <stdio.h>#define STR_OK "[\x1b[1;32m OK \x1b[0m]" #define STR_FAIL "[\x1b[1;31mFAIL\x1b[0m]"…