1

All of a sudden a project that worked fine on webpack 4 now breaks on all browsers while on dev.

I am using Node v16.3.0 & npm v8.1.3

The page loads, the terminal gives out no error and it seems to work, the page can be interacted with for a few seconds then it frezees and the console on the browsers throws:

Uncaught ReferenceError: process is not defined

The build still works well for production it's only breaking on dev.

I have researched and tried everything, changed to different node version use the process plugin, it does not matter always comes back with the same error on the browser console.

This is my webpack.config.js

// Module paths
const path = require('path')
// File System module
const fs = require('fs')
// Main webpack bundler
const webpack = require('webpack')
// Merger for webpack configurations
const merge = require('webpack-merge')
// Created html for bundle
const HtmlPlugin = require('html-webpack-plugin')
// Add Tags
const HtmlWebpackTagsPlugin = require('html-webpack-tags-plugin')
// CSS Linter
const StylelintPlugin = require('stylelint-webpack-plugin')
// On screen error console
const ErrorOverlayPlugin = require('error-overlay-webpack-plugin')
// Tidy up plugings after ise
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// Copy folder
const CopyWebpackPlugin = require('copy-webpack-plugin')
// Module loaders
const load = require('./webpack.modules')
// Get metas
const { links, metas } = require('../meta/meta-data')

// Paths
const paths = {
  app: path.join(__dirname, '../../app'),
  dist: path.join(__dirname, '../../public')
}

// Main module
const commonConfig = merge([
  {
    context: paths.app,
    resolve: {
      unsafeCache: true,
      symlinks: false
    },
    output: {
      path: paths.dist,
      pathinfo: true
    },
    plugins: [
      new HtmlPlugin({
        template: `${paths.app}/index.html`,
        inject: true
      }),
      // Style linter
      new StylelintPlugin({
        context: `${paths.app}/styles`,
        syntax: 'scss',
        emitErrors: false,
        configFile: path.resolve(__dirname, 'stylelint.config.js')
      })
    ]
  },
  load.LintJS({
    include: `${paths.app}/scripts/*`,
    options: {
      emitWarning: true,
      failOnWarning: false,
      failOnError: true,
      fix: true,
      cache: true,
      formatter: require('eslint-friendly-formatter'),
      configFile: path.resolve(__dirname, 'eslint.config.js')
    }
  })
])
// Production module
const productionConfig = merge([
  {
    mode: 'production',
    devtool: false,
    stats: {
      assets: true,
      modules: false,
      children: false
    },
    entry: {
      app: paths.app + '/scripts/index.jsx',
      styles: paths.app + '/styles/index.scss'
    },
    output: {
      filename: 'static/scripts/[name].bundle.[contenthash:8].js'
    },
    optimization: {
      runtimeChunk: 'single',
      splitChunks: {
        chunks: 'all',
        maxInitialRequests: Infinity,
        maxAsyncRequests: 30,
        maxSize: 100000,
        minSize: 0,
        cacheGroups: {
          defaultVendors: {
            test: /[\\/]node_modules[\\/]/,
            name(module) {
              // get the name. E.g. node_modules/packageName/not/this/part.js
              // or node_modules/packageName
              const packageName = module.context.match(
                /[\\/]node_modules[\\/](.*?)([\\/]|$)/
              )[1]
              // npm package names are URL-safe, but some servers don't like @ symbols
              return `npm.${packageName.replace('@', '')}`
            }
          }
        }
      }
    },
    performance: {
      maxEntrypointSize: 470000, // in bytes
      maxAssetSize: 470000, // in bytes
      hints: 'warning' // 'error' or false are valid too
    },
    cache: true,
    plugins: [
      new HtmlWebpackTagsPlugin({ links, metas }),
      new CleanWebpackPlugin(),
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('production')
      }),
      new CopyWebpackPlugin([
        {
          from: `${paths.app}/images/favicon`,
          to: `${paths.dist}/static/images/favicon`
        }
      ])
    ]
  },
  // HTML
  load.Html(true),
  // JS
  load.Scripts({
    include: `${paths.app}/scripts`,
    options: {
      configFile: path.resolve(__dirname, 'babel.config.js'),
      cacheDirectory: true
    }
  }),
  load.MinifyJS({
    extractComments: true,
    cache: true,
    parallel: true,
    sourceMap: false,
    terserOptions: {
      extractComments: 'all',
      parse: { ecma: 8 },
      compress: {
        ecma: 5,
        warnings: false,
        comparisons: false,
        drop_console: true
      },
      mangle: { safari10: true },
      output: {
        ecma: 5,
        comments: false,
        ascii_only: true
      }
    }
  }),
  // CSS
  load.ExtractCSS({
    include: `${paths.app}/styles`,
    options: {
      filename: 'static/styles/[name].min.[contenthash:8].css'
    }
  }),
  load.CSS({
    include: `${paths.app}/node_modules/react-calendar/`
  }),
  load.MinifyCSS({
    options: {
      discardComments: { removeAll: true }
    }
  }),
  // Images
  load.Images({
    include: `${paths.app}/images`,
    options: {
      name: 'static/images/[name].[contenthash:8].[ext]',
      limit: 1000,
      esModule: false
    }
  }),
  load.Fonts({
    include: `${paths.app}/fonts`,
    options: {
      name: 'static/fonts/[name].[contenthash:8].[ext]',
      limit: 5000
    }
  }),
  load.OptimizeImages({
    options: {
      mozjpeg: { progressive: true },
      gifsicle: { interlaced: false },
      optipng: { optimizationLevel: 4 },
      pngquant: { quality: [0.75, 0.9], speed: 3 }
    }
  })
])

// Development module
const developmentConfig = merge([
  {
    mode: 'development',
    entry: [paths.app + '/scripts/index.jsx', paths.app + '/styles/index.scss'],
    cache: true,
    devtool: 'cheap-module-source-map',
    plugins: [
      new HtmlWebpackTagsPlugin({
        links: [
          {
            path: 'data:,',
            attributes: { rel: 'icon' }
          }
        ]
      }),

      new ErrorOverlayPlugin(),
      new CleanWebpackPlugin()
    ],
    resolve: {
      alias: {
        'react-dom': '@hot-loader/react-dom'
      }
    },
    optimization: {
      splitChunks: {
        cacheGroups: {
          default: false
        }
      }
    }
  },
  // Dev server main settings
  load.DevServer({
    host: 'ranks.local',
    port: 3000,
    proxy: {
      '/api': {
        target: 'http://localhost:4000',
        secure: false
      }
    },
    http2: true,
    https: {
      key: fs.readFileSync('/usr/local/etc/nginx/ssl/localhost+3-key.pem'),
      cert: fs.readFileSync('/usr/local/etc/nginx/ssl/localhost+3.pem')
    }
  }),
  // HTML
  load.Html(),
  // JS
  load.Scripts({
    include: `${paths.app}/scripts`,
    options: {
      configFile: path.resolve(__dirname, 'babel.config.js')
    }
  }),
  // CSS
  load.CSS({
    include: `${paths.app}/node_modules/react-calendar/`
  }),
  load.Styles({
    include: `${paths.app}/styles`
  }),
  // Images
  load.Images({
    include: `${paths.app}/images`,
    options: {
      esModule: false,
      limit: 0
    }
  }),
  // Fonts
  load.Fonts({
    include: `${paths.app}/fonts`,
    options: {
      name: `fonts/[name].[hash:8].[ext]`
    }
  })
])

// Merge modules
module.exports = (env) =>
  merge(commonConfig, env === 'dev' ? developmentConfig : productionConfig)

And these are my package.json scripts:

 "scripts": {
    "dev": "webpack-dev-server --config=config/webpack.config.js --env dev --color",
    "build": "webpack --config=config/webpack.config.js --mode=production --progress"
  },

enter image description here

Álvaro
  • 2,255
  • 1
  • 22
  • 48

2 Answers2

0

Your configuration has this:

new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('production')
      }),

in productionConfig, but not in developmentConfig.

If your code is accessing process.env.NODE_ENV somewhere, it will succeed in production but fail in development, which is consistent with what you're experiencing.

Try adding DefinePlugin to the plugins list in developmentConfig and see if it solves the problem.

ack_inc
  • 1,015
  • 7
  • 13
  • Already have but fails just the same, besides I never had it on dev before and it worked well – Álvaro Feb 17 '22 at 11:06
  • Interesting. Have you confirmed that all instances of `process.env.` in your code are covered in the DefinePlugin configuration in your *developmentConfig*? – ack_inc Feb 17 '22 at 11:16
  • What other instances are there, and how can I confirm that? The `DefinedPlugin` was not used before on `developmentConfig` and it all worked fine – Álvaro Feb 17 '22 at 11:18
  • "What other instances are there" -> search through your project's files with `grep -rn process.env src/*" (if your code is in the src folder), or your IDE's built-in search feature – ack_inc Feb 17 '22 at 14:30
  • If another dev working on this project added DefinePlugin to the `productionConfig` of your project recently, but forgot to also add it to `developmentConfig`, that would also cause the situation you're in. – ack_inc Feb 17 '22 at 14:32
  • I am the only one using this repo, and there never was `DefinePlugin` on the `developmentConfig` also as per my answer it works and still there is no `DefinePlugin` on dev – Álvaro Feb 17 '22 at 15:18
0

I am completely buffled by this, it has kind of fixed by itself and I don't know how.

I installed this

$ npm i -D react-error-overlay@6.0.9

And then it worked but this package does not show on the package.json

Álvaro
  • 2,255
  • 1
  • 22
  • 48