【问题标题】:Uncaught TypeError: Cannot read property 'call' of undefined at __webpack_require__未捕获的类型错误:无法读取 __webpack_require__ 处未定义的属性“调用”
【发布时间】:2022-04-02 01:17:39
【问题描述】:

我正在使用 React.lazy 在运行时加载一些 React 类,这样它们就不会一次全部加载。我的代码适用于生产,但在我处于开发模式时崩溃。 (更新:我的代码不再适用于生产环境 - 见下文)。

特定的错误消息非常神秘,因此很难确切知道问题所在:

Uncaught TypeError: Cannot read property 'call' of undefined at __webpack_require__ (main.js:64)

The above error occurred in one of your React components:
    in Unknown
    in Suspense
    in div (created by Main)
    in Main (created by Route)
    in Route (created by App)
    in Switch (created by App)
    in div (created by App)
    in Router (created by BrowserRouter)
    in BrowserRouter (created by App)
    in App

Consider adding an error boundary to your tree to customize error handling behavior.

Uncaught (in promise) TypeError: Cannot read property 'call' of undefined at __webpack_require__ (main.js:64)

第 64 行给出以下代码:

modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

我还有其他没有任何问题的 React 类。

我创建的特定类文件称为 Categories.js。据我所知,我加载该类的方式与任何正在运行的类没有任何不同。我什至尝试重命名类/文件,并且我还删除了大部分数据,以防文件中的某些内容导致问题。

以下是我的代码中的相关行:

import React, {Suspense} from 'react';
....
const Categories = React.lazy(()=> import('./Categories'))
....
return (
    <Suspense fallback={<div>Loading...</div>}>
        <Categories class_select={class_select} />
    </Suspense>
 )

如果有帮助,这里是我的 webpack.config.js 文件:

const HtmlWebPackPlugin = require("html-webpack-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = (env, argv) => {

  const isProduction = (argv.mode === "production")
  return {

          module: {
            rules: [
              {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                  loader: "babel-loader",
                  options: {
                    plugins: [
                        "@babel/plugin-syntax-dynamic-import"
                    ]
                  }
                }
              },
              {
                test: /\.html$/,
                use: [
                  {
                    loader: "html-loader"
                  }
                ]
              }
            ]
          },
          ...(isProduction && {
                  optimization: {
                   // minimize: true,
                    minimizer: [
                        new TerserPlugin({
                                terserOptions: {
                                        extractComments: 'all',
                                        compress: {
                                                drop_console: true
                                        },

                                }
                        })
                    ],
                  }
          }),
          devtool: !isProduction && 'eval-source-map',
          plugins: [
            new HtmlWebPackPlugin({
              template: "./src/index.html",
              filename: "./index.html"
            }),
            new CopyPlugin([
              { from: 'src/css', to: 'css' }
            ])
          ]
     };
};

问题

1) 是什么导致了这个错误? 2) 为什么它只在开发模式下引起,而不是在生产模式下引起?

更新

我的代码也不再适用于生产环境。我收到以下错误:

Uncaught (in promise) TypeError: Cannot read property 'call' of undefined at o (main.js:2). 

事实上,它在生产环境中甚至比开发环境更糟糕。在生产中,没有一个 React 惰性类在工作。在 dev 中,只有其中一个不起作用。

【问题讨论】:

  • 我不知道你在解决这个问题上走了多远,我站在我这边试图找到一个解决方案。原因之一似乎与代码的优化有关。如果我理解正确的话,issues of naming between the JS files when the package is built 会导致某些文件丢失对模块的引用,从而导致“未定义”问题。我还在努力,如果我找到解决方案,我会回到你的问题。

标签: javascript reactjs webpack


【解决方案1】:

流程

为了找到这个问题的潜在解决方案,我不得不修改优化模块,这确实是这里的问题,即使没有令人惊讶地启用。 我最好的猜测是某些参数在production 模式下设置为默认值,而不是在dev 模式下,这会导致导入和未定义属性的问题。

我决定尝试复制部署环境并检查我是否至少可以“破坏”开发并从这里调查问题。这些是生产和开发之间不同的参数,并且可能会导致手头的问题(您可以通过切换到相反的值来尝试自己放置 deployment,例如 development 环境)。

在我在评论中提供的link 上,用户解释说问题出在部署级别,并且vendors 块的构建方式与main 块碰撞并切断@987654331 @ 彼此。解决方案之一是显然使用concatenateModules: false,但无济于事,它并没有解决我的问题。所以我和其他人一起尝试,发现了下面的问题。

可能的解决方案

module.exports 中,应编辑optimization 对象

optimization: {
    minimize: true,
    namedModules: true,
    namedChunks: true,
    removeAvailableModules: true,
    flagIncludedChunks: true,
    occurrenceOrder: false,
    usedExports: true,
    concatenateModules: true,
    sideEffects: false, // <----- in prod defaults to true if left blank
}

编辑:所有这些参数都设置为生产和开发之间的对立面,您可以随意调整它们,一些问题源于它们

说明

切换所有参数后,我发现sideEffects 是一个破坏事物的那个,我明白为什么了:

sideEffects flag 将按照 documentation on sideEffects 将导入分解为单独的导入:

import { a, b } from "big-module-with-flag"

被改写为

import { a } from "big-module-with-flag/a";
import { b } from "big-module-with-flag/b";

并且会尝试在模块中相应地优化导入,这可能会导致生产问题。通常,这应该有助于通过减少捆绑包来优化包的大小,但代价是删除了一些导入,但可能会在导入时破坏。

我希望解释清楚一些,如果有人对 WebPack 优化有更深入的了解,欢迎提供任何文档和增强功能。

【讨论】:

  • 还以为是sideEffects 标志,对我来说有帮助的是将v4 webpack4.12 升级到latest (4.45),最小的有用版本是4.30(固定github.com/webpack/webpack/pull/8916,和chunks有关)
  • 非常感谢您发布完整的optimizations 对象,并将其所有选项切换为相反的值!将这个列表一分为二,我节省了几个小时来调查我的非常具体的问题。
【解决方案2】:

我也遇到了同样的错误,从缩小的 JavaScript 堆栈跟踪中很难诊断出根本原因。最后,我只是将 Webpack 版本升级到最新的 4.X 稳定版本(我使用的是 Angular 11,所以不支持 Webpack 5),问题就神奇地消失了。假设我之前使用的 Webpack 4.2.X 版本中一定存在一些依赖树错误。

Webpack 版本参考: https://www.npmjs.com/package/webpack

命令

npm uninstall webpack
npm install --save-dev webpack@4.46.0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-22
    • 2021-04-22
    • 2015-01-06
    • 2019-07-31
    • 2017-07-26
    • 2019-02-26
    相关资源
    最近更新 更多