【问题标题】:path.join in require statementpath.join 在 require 语句中
【发布时间】:2019-05-27 10:45:11
【问题描述】:

我尝试在require 语句中使用Path.join,如下所示:

import Path from 'path'

const assetPath = Path.join(process.cwd(), `./lib/asset-manifest.json`)

console.log(assetPath)
'/home/dev/Website/lib/asset-manifest.json'

console.log(
  assetPath === '/home/dev/Website/lib/asset-manifest.json'
)
true

const assets = require(assetPath)

但这会引发以下错误:

Error: Cannot find module '/home/dev/Website/lib/asset-manifest.json'

虽然文件在那里并且require 工作,但如果我手动将字符串放入其中:

const assets = require('/home/dev/Website/lib/asset-manifest.json')

所以我想知道为什么Path.join 不能在require 中工作?

最好的问候

【问题讨论】:

  • 一个 string 是一个 string 并且 两个 相同的字符串仍然是相同的。您是否试图断言它们是相同的? console.log(assetPath === '/home/dev/Website/lib/asset-manifest.json'); 因为变量或文字的使用对require() 没有影响。
  • @cgTag 是的,他们是平等的。
  • 你这个路径上真的有文件吗,试试系统终端类型:cat /home/dev/Website/lib/asset-manifest.json 你能看到任何文字吗?
  • @VadimHulevich 是的 cat 有效。我使用 webpack。可能是 webpack 的问题?
  • 你为什么在 nodejs 中使用 webpack?你在建图书馆吗?

标签: javascript node.js webpack dynamic


【解决方案1】:
import path from 'path';

// you can use process.cwd() if you want
const assetPath = path.join(path.dirname(require.main.filename), `lib/asset-manifest`);

const test = () => {
  var assets = require(assetPath);
  console.log(assets);
};

export default test();

您需要将 require 包围在函数内。否则 require 将在路径分配给assetPath 变量之前运行。这是因为 require 是 SYNC 并且从调用它的文件或函数的角度运行。因为你说这是必需的,所以它会在其他任何事情之前立即执行。

前进的最佳实践是停止对 json 文件使用 require。需要缓存内容,因此如果生产环境中的 JSON 文件发生更改,您的用户可能会获得旧数据。而是使用fs.readfile(path, (err, data) => JSON.parse(data))

有一个 webpack 配置你可能想在你的情况下尝试。

WEBPACK DOCS: Don't Check Require Dependencies

WEBPACK DOCS: Generate Require Func

const requireJSON = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
const assets = requireJSON(assetPath);

这应该返回所有可能的需求路径。

【讨论】:

  • 有webpack配置可以自动解决这个问题吗?
  • 我有一个问题。您是要将此要求/导入推迟到运行时还是要编译?
  • 查看更新的答案!这对您有帮助吗?
  • @MERN 我想跟进,看看您是否能够查看我的回复。如果您有任何其他问题或者我可以提供任何进一步的帮助,请告诉我。谢谢
【解决方案2】:

webpack 是一个静态模块捆绑器,这里的require 不像nodejs 中的require

前一个包含静态编译阶段的文件,另一个包含运行时的文件。

您的情况,const assets = require(assetPath)assetPath 未在静态编译阶段定义,这就是抛出错误的原因。

让我们看看捆绑的结果:

// const assets = require(assetPath);
const assets = await __webpack_require__("./ lazy recursive")(assetPath);

// below is the "./ lazy recursive" module
function webpackEmptyAsyncContext(req) {
    // Here Promise.resolve().then() is used instead of new Promise() to prevent
    // uncaught exception popping up in devtools
    return Promise.resolve().then(() => {
        var e = new Error("Cannot find module '" + req + "'");
        e.code = 'MODULE_NOT_FOUND';
        throw e;
    });
}
webpackEmptyAsyncContext.keys = () => ([]);
webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
webpackEmptyAsyncContext.id = "./ lazy recursive";
module.exports = webpackEmptyAsyncContext

【讨论】:

  • webpack is a static module bundler, 是什么意思?
  • 有其他方法可以代替 webpack 吗?
  • @MERN 您可以改用“gulp”。顺便说一句,nodejs中使用的模块系统是commonjs,你应该使用require/exports来包含你的文件而不是import/export
猜你喜欢
  • 2014-11-28
  • 2015-01-26
  • 2022-08-20
  • 1970-01-01
  • 2023-01-28
  • 2020-11-06
  • 2020-06-30
  • 1970-01-01
  • 2018-06-24
相关资源
最近更新 更多