ESM 相当于 createRequire(path).resolve(module)

问题描述 投票:0回答:1

我正在开发一个 JavaScript 检测引擎,我会遍历源文件的 AST 并递归地将导入的模块排队以进行检测。为此,我需要将模块名称解析为其源文件。

对于 CommonJS 模块,这非常简单:

/**
 * Resolves the given module to a path.
 * @param currentFilePath The file that is currently instrumented. Serves as base path for the resolver.
 * @param module The module to resolve to its file path.
 */
function resolveCommonJsModule(currentFilePath, module)
{
  let requireFunc = createRequire(currentFilePath);
  return requireFunc.resolve(module);
}

但是,这对于通过

import
加载的ES模块不起作用。如果库在其 package.json 中定义了 ES 和 CommonJS 模块的单独导出,则此函数将始终返回 CommonJS 版本。例如:

...
"exports": {
    ".": {
      "types": "./index.d.ts",
      "import": "./esm/index.js",  <-- ES module
      "default": "./index.js"      <-- CommonJS module, which is returned by function above
    },
},
...

我知道有

import.meta.resolve()
,但这不允许我设置完成解析的“基本路径”。相反,它与检测脚本相关,后者位于完全不同的目录中。

用于解析给定基本路径的模块名称的 ES 模块等效项是什么?

javascript node.js node-modules es6-modules
1个回答
0
投票

实际上存在不稳定的重载

import.meta.resolve(specifier, parent)
,这将允许解析相对于给定
parent
模块的导入,类似于
require.resolve

但是,它需要

--experimental-import-meta-resolve
标志,并且似乎不适用于所有模块:解析
./file.mjs
成功,但解析
some-package
会导致
ERR_MODULE_NOT_FOUND

幸运的是,我找到了一个可以解决该问题的 ponyfill,import-meta-resolve

import * as importMetaResolve from "import-meta-resolve";

let modulePath = importMetaResolve.resolve(module, pathToFileURL(currentFilePath));

此命令生成所有 CommonJS 和 ES 模块的正确路径。

© www.soinside.com 2019 - 2024. All rights reserved.