module.exports 依赖项(导入)不可用

module.exports not available on dependency (import)

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

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

/*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; 覆盖了 Node 在调用 import 时提供的任何值。为了验证假设,我删除了 var 模块; 并将其作为函数的参数删除,一切正常。当然,这不是我的问题的答案,因为这是一个依赖库,我无权触摸它的代码。

我无法弄清楚升级到 Webpack 5 可能会破坏什么,从而无法使 module.exports 可用于 countdown.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"
          //     },
          //   },
          // ],
        },
      ],
    }

None 那项工作。我不太明白 Webpack 5 中发生了什么变化导致倒计时导出库的方式中断。

有什么想法吗?

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

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

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

原来包已更新,但版本更新尚未传播。有一个 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"
  },