Webpack unexpected behavior TypeError: Cannot read property 'call' of undefined

Viewed 4520

Recently we have updated webpack to v4 and soon noticed unexpected errors from webpack during development, which disappears after rebuild of entire bundle.

Our application build using lazy loading and code splitting, which can cause the issue, though I couldn't find anything related to this in the official documentations.

Here the error we get

react_devtools_backend.js:2273 TypeError: Cannot read property 'call' of undefined

enter image description here

our webpack webpack.config.js file.

const webpack = require('webpack');
const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const AssetsPlugin = require('assets-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
// minification plugins
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
// image optimization plugins
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const imageminGifsicle = require("imagemin-gifsicle");
const imageminPngquant = require("imagemin-pngquant");
const imageminSvgo = require("imagemin-svgo");
const imageminMozjpeg = require('imagemin-mozjpeg');
const env = require('dotenv').config();

const isProd = process.env.NODE_ENV === 'production';
const isDev = !isProd;

const environment = {
    NODE_ENV: process.env.NODE_ENV || 'development',
    CONFIG: process.env.CONFIG || 'development',
    DEBUG: process.env.DEBUG || false,
};

const plugins = () => {
    let plugins = [
        new CleanWebpackPlugin(['build', 'cachedImages'], {
            root: path.resolve(__dirname, '../dist'),
            verbose: true,
            dry: false,
        }),
        new webpack.EnvironmentPlugin(Object.assign(environment, env.parsed)),
        new MiniCssExtractPlugin('[chunkhash:5].[name].[hash].css'),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            moment: 'moment',
            _: 'lodash',
        }),
        new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en)$/),
        new AssetsPlugin({
            filename: 'assets.json',
        }),
        new ImageminPlugin({
            cacheFolder: isDev ? path.resolve(__dirname, '../dist/cachedImages') : null,
            externalImages: {
                context: 'src',
                sources: glob.sync('src/assets/img/**/*.*'),
                destination: 'dist/img/',
                fileName: (filepath) => {
                    let name = filepath.split(/img(\/|\\)/).pop();
                    return name;
                },
            },
            plugins: [
                imageminGifsicle({
                    interlaced: false
                }),
                imageminMozjpeg({
                    progressive: true,
                    arithmetic: false
                }),
                imageminPngquant({
                    floyd: 0.5,
                    speed: 2
                }),
                imageminSvgo({
                    plugins: [
                        { removeTitle: true },
                        { convertPathData: false }
                    ]
                }),
            ],
        }),
    ];

    if (isProd) {
        plugins.push(
            new BundleAnalyzerPlugin({
                analyzerMode: 'static',
                reportFilename: path.resolve(__dirname, 'analysis.html'),
                generateStatsFile: false,
                logLevel: 'info',
            })
        );
    }

    return plugins;
};

const optimization = () => {
    let optimizations = {
        concatenateModules: true,
        splitChunks: {
            cacheGroups: {
                vendor: {
                    name: 'vendor',
                    test: /[\\/]node_modules[\\/](react|react-dom|lodash|moment)[\\/]/,
                    chunks: 'all',
                },
                commons: {
                    chunks: 'async',
                }
            }
        }
    };

    if (isProd) {
        optimizations.minimizer = [
            new TerserJSPlugin({
                terserOptions: {
                    compress: {
                        pure_funcs: ['console.log'],
                        drop_console: true,
                        drop_debugger: true
                    },
                    warnings: false
                },
                parallel: true
            }),
            new OptimizeCSSAssetsPlugin({})
        ];
    }

    return optimizations;
};

const fontLoaders = [
    {
        test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
        use: {
            loader: 'url?limit=10000&mimetype=application/font-woff',
        }
    },
    {
        test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
        use: {
            loader: 'url?limit=10000&mimetype=application/font-woff',
        }
    },
    {
        test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
        use: {
            loader: 'url?limit=10000&mimetype=application/octet-stream',
        }
    },
    {
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        use: {
            loader: 'url?limit=10000&mimetype=image/svg+xml',
        }
    },
    {
        test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
        use: {
            loader: 'file',
        }
    }
];

const config = {
    mode: process.env.NODE_ENV,
    devtool: isDev ? 'source-map' : '',
    context: path.resolve(__dirname, '../src'),
    entry: {
        bundle: './app.jsx',
        embed: './embed.jsx',
        styles: './sass_new/main.scss',
        vendor: [
            'react',
            'react-dom',
            'redux',
            'redux-saga',
            'react-redux',
            'react-router',
            'react-tap-event-plugin',
            'lodash',
            'moment',
        ]
    },
    output: {
        publicPath: '/build/',
        filename: '[name].[hash].js',
        chunkFilename: '[name].[hash].js',
        path: path.resolve(__dirname, '../dist/build'),
    },
    resolve: {
        extensions: ['.js', '.jsx', '.json'],
        alias: {
            config: path.resolve(__dirname, '../config.js'),
            utils: path.resolve(__dirname, '../src/utils'),
            shared: path.resolve(__dirname, '../src/components/shared'),
            services: path.resolve(__dirname, '../src/services'),
            store: path.resolve(__dirname, '../src/store'),
            constants: path.resolve(__dirname, '../src/constants'),
            actions: path.resolve(__dirname, '../src/actions'),
            components: path.resolve(__dirname, '../src/components'),
        },
    },
    optimization: optimization(),
    plugins: plugins(),
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: [/node_modules/, /libs/],
                use: {
                    loader: path.join(__dirname, '../helpers/custom-loader.js'),
                    options: {
                        presets: ['@babel/preset-env', '@babel/preset-react'],
                        plugins: [
                            '@babel/plugin-proposal-object-rest-spread',
                            '@babel/plugin-proposal-class-properties',
                            '@babel/plugin-transform-destructuring',
                            '@babel/plugin-syntax-dynamic-import',
                            '@babel/plugin-transform-runtime',
                            'syntax-async-functions'
                        ]
                    }
                }
            },
            {
                test: /\.scss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    'css-loader',
                    'sass-loader',
                ]
            },
            {
                test: /\.css$/,
                use: [
                    'css-loader'
                ]
            },
            {
                test: /\.(jpe?g|png|gif|svg)$/i,
                loader: "url-loader",
                options: {
                    name: "[path][name].[ext]"
                },
            },
            ...fontLoaders
        ]
    },
    watchOptions: {
        ignored: /node_modules/,
    },
};

module.exports = config;

I have no idea how to fix this, and it's taking a lot of time to rebuild entire app after getting this error.

0 Answers
Related