【问题标题】:module.exports not available on dependency (import)module.exports 在依赖项(导入)上不可用
【发布时间】:2021-09-29 19:07:49
【问题描述】:

最近将一个项目升级到 Gatsby 3,其依赖项是 Webpack 5。在其中一个 .tsx 类中,完成了对库 countdown 的导入。 import 每次都会返回一个空对象,{}。

查看“倒计时”库中的代码,我看到他们像这样导出模块:

/*global window */
var module;

var countdown = (
    
function(module) {
    'use strict';
    ...
    if (module && module.exports) {
        module.exports = countdown;

    } else if (typeof window.define === 'function' && typeof window.define.amd !== 'undefined') {
        window.define('countdown', [], function() {
            return countdown;
        });
    }
    return countdown;
})(module);

在库中使用 console.log 我看到 module.exports 实际上是未定义的,似乎 var module; 覆盖了任何东西当调用 import 时,节点使值可用。为了验证假设,我删除了 var 模块; 并将其作为函数的参数删除,一切正常。当然,这不是我的问题的答案,因为这是一个依赖库,我无权触摸它的代码。

我不知道升级到 Webpack 5 可能会破坏什么,即使 module.exportscountdown.js 可用,即使他们声明了变量。

我查看了webpack updates 并试图告诉它在countdown.js 上使用commonjs 或import-loader 并将它传递给“模块”(不同的测试用例已被注释掉):

module: {
      rules: [
        {
          test: /\countdown.js?$/,
          use: {
            loader: 'babel-loader',
          },
          // loader: "imports-loader",
          // options: {
          //   syntax: "default",
          //   type: "commonjs"
          // },
          // use: [
          //   {
          //     loader: "imports-loader",
          //     options: {
          //       thisArg: "module"
          //     },
          //   },
          // ],
        },
      ],
    }

这些都不起作用。我不太清楚 Webpack 5 中发生了什么变化导致 countdown 导出库的方式中断。

有什么想法吗?

明确一点:库 countdown 不是我的,在使用以前的 webpack 版本时,它在导入和使用时效果很好。

【问题讨论】:

  • 这并不能解决您的问题,但Of course, that's not the answer to my problem since this is a dependency library, I have no right to touch its code. 并非如此,您总是可以为开源项目创建问题和/或拉取请求。
  • webpack 5 现在似乎以不同的方式对待module。更像是一个关键字而不是一个全局变量。因此,拥有var module 将影响 "global" module。但我可以找到任何能对此提供更多见解的东西。
  • 你在@t.niese 上是对的,我可以提出拉取请求。
  • 我在调查问题时检查了 countdownjs 库,但它似乎没有得到维护。最后一次提交是 6 年前。

标签: javascript reactjs webpack webpack-5


【解决方案1】:

原来包已更新,但版本更新尚未传播。有一个request 正在征求那个。

与此同时,一位同事有一个解决方案,我想我会在这里分享它,以防在版本更新之前任何人都可以使用它。总之,它会在安装完成后从库中修改脚本,它会删除声明的全局变量,该变量会覆盖 Node 应该传递的全局变量。

在一个名为 yarn-postinstall.js(或任何你喜欢的)的文件中:

fixCountdownLib();

function fixCountdownLib() {
  const fs = require("fs");

  const countdownLibPath = __dirname + "/node_modules/countdown/countdown.js";
  const countdownLibCode = fs.readFileSync(countdownLibPath).toString();

  const fixedCountdownLibCode = countdownLibCode.replace("var module;", "");

  fs.writeFileSync(countdownLibPath, fixedCountdownLibCode);
}

然后更新 package.json 脚本以指向该文件。

  "scripts": {
    "postinstall": "node yarn-postinstall.js"
  },

【讨论】:

    【解决方案2】:

    module 变量不是 object,也没有属性 exports

    var module; 更改为var module = {exports: {}} 应该可以。但我不确定您是否应该检查module.exports,因为我猜它应该是undefined

    【讨论】:

    • 定义了“var module”的库不是我的,我不能编辑它。使用 webpack 4 时它运行良好,是更新导致它无法运行。
    • @Chayemor 这可能是 webpack 的一个错误。
    猜你喜欢
    • 2020-11-28
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    相关资源
    最近更新 更多