【问题标题】:NodeJS - How to get the directory path of the script that required my module?NodeJS - 如何获取需要我的模块的脚本的目录路径?
【发布时间】:2022-01-26 02:19:28
【问题描述】:

我正在制作一个简单的模块 require 脚本(以“草率”模式运行),以使使用常规 NodeJS 的 require 模块更简单。 这是我当前的代码,我会告诉你我在此之后遇到的问题:

const util = require('./util.js')

const path = require('path')
const fs = require('fs')

module.exports = function (...requirements) {
    let modulel = {}

    modulel.requireAll = function () { 
        requirements.forEach((requirement) => {
            if (util.getType(requirement) === 'String') {
                let pr = requirement;
                if (fs.existsSync(path.join(__dirname, pr))) { /// Always returns false
                    let pname = path.basename(pr);

                    this[pname] = require(path.join(__dirname, pr)); /// Always throws an error.
                }
                else {
                    let pname = requirement.replace(/[^A-Za-z0-9$_]/g,'').replace('.','').replace('/','').replace('js','');

                    this[pname] = require(pr);
                }
            }
        })
    }

    if (!(requirements === null || requirements === undefined)) modulel.requireAll();

    return module
}

应该是这样的用法

require('simplyrequire')('express', './util.js')

const app = express();

const bar = util.foo();

那么,我该如何解决这个错误呢?

Error: Cannot find module 'C:\Users\*****\OneDrive\Documents\requireall\express'
Require stack:
- C:\Users\*****\OneDrive\Documents\requireall\index.js
- C:\Users\*****\OneDrive\Documents\requireall\test\test.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at C:\Users\*****\OneDrive\Documents\requireall\index.js:16:20
    at Array.forEach (<anonymous>)
    at Object.modulel.requireAll (C:\Users\*****\OneDrive\Documents\requireall\index.js:10:16)
    at module.exports (C:\Users\*****\OneDrive\Documents\requireall\index.js:27:70)
    at Object.<anonymous> (C:\Users\*****\OneDrive\Documents\requireall\test\test.js:1:37)
    at Module._compile (node:internal/modules/cjs/loader:1101:14) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Users\\*****\\OneDrive\\Documents\\requireall\\index.js',
    'C:\\Users\\*****\\OneDrive\\Documents\\requireall\\test\\test.js'
  ]
}

当我将 (fs.existsSync) 替换为 (!fs.existsSync) 以测试路径加入相对路径和执行脚本的目录时会发生这种情况。

但是就执行脚本的目录而言,如果文件存在与否,我将如何获得?我这样做对吗?如果我翻转它,它会起作用!回到常规的 if true 陈述?因为这似乎仍然行不通,而且我对整个代码在未来被弃用的信心仍然很低。

有什么帮助吗?谢谢。

【问题讨论】:

  • 您可能想查看peer dependencies
  • require.parent.filename 是加载您的模块的完整文件名。但是,对于require('simplyrequire')('express', './util.js') 后跟const app = express();,您似乎尝试做的任何事情都没有意义。您将要求其他模块中的函数在此模块中定义变量。据我所知,Javascript 不是这样工作的。而且,我认为这在 ESM 模块中是不可能的,这也是语言和 nodejs 的方向(所以我不会在只与 CommonJS 兼容的代码上投入太多)。
  • IMO,您不应该试图绕过在 nodejs 中定义和使用的模块加载方案,只是为了节省几个字符的输入。没有人会知道如何阅读您的代码。它不适用于 ESM 模块。无论如何,您不能要求其他模块中的函数在父模块中定义变量。试图重新发明这一切真的没有意义。
  • 而且,这个require('simplyrequire')('express', './util.js') 到底是怎么搞的?您试图混淆模块加载和变量定义。目的是什么?

标签: javascript node.js require


【解决方案1】:

require.main.path 给出了第一次作为选项传递给节点的脚本的路径

【讨论】:

    【解决方案2】:

    我将忽略您显示的代码中的不同问题,只关注主要问题,这对我来说很有趣:如何在 Node.js 中获取需要我的模块的脚本的目录路径。 js?

    有不同的方法,但没有外部依赖的最简单的解决方案是使用 V8 stack trace API 找出包含调用函数的代码的文件,然后取出目录部分。

    所以你可以在你的simplyrequire.js 中有这样的东西:

    // simplyrequire.js
    const { dirname } = require('path');
    
    module.exports = () => {
        let callerPath;
        const error = { };
        Error.captureStackTrace(error);
        Error.prepareStackTrace = (error, callSites) => {
            callerPath = callSites[1]?.getFileName();
        };
        void error.stack;
        delete Error.prepareStackTrace;
        if (callerPath != null) {
            const dir = dirname(callerPath);
            console.log('Called from a file in directory %s', dir);
        }
    };
    

    然后,当你调用另一个文件时

    // main.js
    require('simplyrequire')();
    

    您应该在日志中看到包含 main.js 的目录的路径。

    同样,您需要先解决代码中的其他问题,然后才能实现您想要的目标,但这应该是您的一个开始。

    【讨论】:

      猜你喜欢
      • 2017-07-04
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-10
      • 1970-01-01
      • 2012-12-03
      相关资源
      最近更新 更多