Uncaught TypeError: Nu se poate citi proprietatea ‘call’ a unui nedefinit la __webpack_require__ (Programare, Javascript, Reactjs, Webpack)

kojow7 a intrebat.
a intrebat.

Folosesc React.lazy pentru a încărca unele clase React în timpul execuției, astfel încât să nu fie încărcate toate deodată. Codul meu funcționează pentru producție, dar se blochează atunci când sunt în modul de dezvoltare. (UPDATE: Codul meu nu mai funcționează în producție – a se vedea mai jos).

Mesajul de eroare particular este foarte criptic, așa că este greu de știut exact care este problema:

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)

Linia 64 dă următorul cod:

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

Am alte clase React care nu au nicio problemă.

Fișierul de clasă special pe care l-am creat se numește Categories.js. Din câte știu eu, nu încarc clasa în mod diferit față de oricare dintre cele care funcționează. Am încercat chiar să redenumesc clasa/fișierul și, de asemenea, am eliminat majoritatea datelor mele din el în cazul în care ceva din fișier ar fi cauzat problema.

Iată liniile relevante din codul meu:

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

Dacă vă ajută, aici este fișierul meu 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' }
            ])
          ]
     };
};

Întrebări

1) Ce cauzează această eroare?2) De ce este cauzată doar în modul dev, dar nu și în modul de producție?

Actualizare

Codul meu nu mai funcționează nici în producție. Primesc următoarea eroare:

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

De fapt, este chiar mai rău în producție decât în dev. În producție nu funcționează niciuna dintre clasele React lazy. În dev este doar una dintre ele care nu funcționează.

Comentarii

  • Nu știu cât de departe ați ajuns în rezolvarea acestei probleme, eu sunt de partea mea și încerc să găsesc o soluție. Una dintre cauze pare să fie legată de optimizarea codului. Dacă am înțeles bine există probleme de denumire între fișierele JS atunci când pachetul este construit ceea ce face ca unele fișiere să piardă referința la module, de unde și problemele „nedefinite”. Încă lucrez la asta, dacă găsesc o soluție voi reveni la întrebarea ta. –  > Por Pierre Chevallier.
2 răspunsuri
Pierre Chevallier

Proces

Pentru a găsi o potențială soluție la această problemă, a trebuit să mă joc cu modulul de optimizare, care a fost într-adevăr problema aici, chiar și atunci când nu a fost activat în mod surprinzător. cea mai bună presupunere a mea este că unii parametri sunt setați în mod implicit în production mod și nu în dev mod și acest lucru cauzează probleme de importuri și proprietăți nedefinite.

Am decis să încerc replicarea mediului de implementare și să verific dacă aș putea măcar să „sparg” dezvoltarea de asemenea și să investighez problema de aici. Aceștia sunt parametrii care sunt diferiți între producție și dezvoltare și care au fost suspectați că au cauzat problema în cauză (puteți încerca și dumneavoastră trecând la valoarea opusă pentru a pune deployment cum ar fi development mediu, de exemplu).

La link-ul pe care am furnizat-o în comentariu, utilizatorul explica faptul că problema era la nivel de implementare și că modul în care a fost implementat vendors era construit, se ciocnea cu main chunks și taie entry unul de altul. Una dintre soluții a fost să se folosească concatenateModules: false aparent, dar fără succes, nu a rezolvat problema mea. Așa că am încercat cu celelalte și am găsit problema de mai jos.

Soluție potențială

în module.exports, , la optimization ar trebui să fie editat obiectul

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
}

Edit: toți acești parametri sunt setați la opusul lor între producție și dezvoltare, modificați-i după bunul plac, unele probleme decurg din ei

Explicație

După ce am schimbat toți parametrii am constatat că sideEffects unul este cel care strică lucrurile și înțeleg de ce:

The SideEffects flag va descompune importurile în importuri separate, după cum urmează, în conformitate cu documentația privind sideEffects:

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

se rescrie în

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

Și va încerca să optimizeze importurile în mod corespunzător în toate modulele, ceea ce poate cauza probleme în producție. În mod normal, acest lucru ar trebui să ajute la optimizarea dimensiunii pachetului prin reducerea pachetelor, cu prețul eliminării unor importuri, dar poate strica lucrurile la import.

Sper că explicația a fost oarecum clară, dacă cineva are cunoștințe mai aprofundate despre optimizarea WebPack, orice documentație și îmbunătățire ar fi binevenită.

Comentarii

  • De asemenea, am crezut că este sideEffects steag, ceea ce a ajutat în cazul meu a fost actualizarea v4 webpack de la 4.12 la latest (4.45), versiunea minimă de ajutor a fost 4.30 (fixat github.com/webpack/webpack/pull/8916, , care are ceva de-a face cu chunks) –  > Por Dr1Ku.
  • Mulțumesc mult pentru postarea completă optimizations obiect cu toate opțiunile sale comutate la valoarea opusă! Bifurcarea acestei liste tocmai mi-a salvat câteva ore de investigație a problemei mele foarte specifice. –  > Por nilfalse.
Dazzle

Am reușit să rezolv această problemă schimbând

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

în

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