首页 > 解决方案 > module.exports 在依赖项(导入)上不可用

问题描述

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

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

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

我不知道升级到 Webpack 5 可能会破坏哪些模块.exports 不能用于countdown.js 即使它们声明了变量。

我查看了webpack 更新并试图告诉它在 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 导出库的方式中断。

有任何想法吗?

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

标签: javascriptreactjswebpackwebpack-5

解决方案


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

与此同时,一位同事有一个解决方案,我想我会在这里分享它,以防任何人都可以使用它,直到版本更新。总之,它在安装完成后从库中修改脚本,它删除了声明的全局变量,该变量覆盖了 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"
  },

推荐阅读