未捕获的TypeError:无法读取__webpack_require__上未定义的属性“调用”

时间:2019-09-24 05:30:36

标签: javascript reactjs webpack

我正在使用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). 

实际上,在生产上它甚至比dev更糟糕。在生产中,React惰性类都不起作用。在开发人员中,只有其中之一无法正常工作。

2 个答案:

答案 0 :(得分:2)

过程

为了找到可能解决此问题的方法,我不得不修改优化模块,即使在未启用此功能的情况下,这确实是这里的问题。 我最好的猜测是,某些参数在production模式下设置为默认值,而不是在dev模式下设置为默认值,这会导致导入和未定义属性的问题。

我决定尝试复制部署环境,并检查我是否至少也可以“破坏”发展,并从此处调查问题。这些参数在生产和开发之间是不同的,并且可能导致问题出现(例如,您可以通过切换为相反的值来尝试自己的deployment,例如developpment环境) )。

在我在评论中提供的link上,用户正在解释问题在于部署级别,并且vendors块的构建方式正在与main发生冲突块并将entry切成彼此。解决方案之一是显然使用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优化有更深入的了解,欢迎提供任何文档和增强功能。

答案 1 :(得分:0)

我能够通过更改来解决此问题

map.on('moveend', update());

map.on('moveend', function () {
    update();
});