Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ModuleNotFoundError with hard crash on file rename/move/delete #5256

Closed
NathZ1 opened this issue Aug 2, 2024 · 4 comments
Closed

ModuleNotFoundError with hard crash on file rename/move/delete #5256

NathZ1 opened this issue Aug 2, 2024 · 4 comments

Comments

@NathZ1
Copy link

NathZ1 commented Aug 2, 2024

Bug report

I renamed a file in my project called Table.tsx to Table2.tsx file webpack-dev-server was running. This consistancy causes the crash to occur. Happens with rename/move/delete of any file within project src.

error from IDE console:

<e> [webpack-dev-middleware] ModuleNotFoundError: Module not found: Error: Can't resolve './Table' in 'C:\dev\shifts\shifts\src\pages\teamConfig\allocations'
<e>     at C:\dev\shifts\shifts\node_modules\webpack\lib\Compilation.js:2100:28
<e>     at C:\dev\shifts\shifts\node_modules\webpack\lib\NormalModuleFactory.js:904:13
<e>     at eval (eval at create (C:\dev\shifts\shifts\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:10:1)
<e>     at C:\dev\shifts\shifts\node_modules\webpack\lib\NormalModuleFactory.js:341:22
<e>     at eval (eval at create (C:\dev\shifts\shifts\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:9:1)
<e>     at C:\dev\shifts\shifts\node_modules\webpack\lib\NormalModuleFactory.js:518:22
<e>     at C:\dev\shifts\shifts\node_modules\webpack\lib\NormalModuleFactory.js:151:11
<e>     at C:\dev\shifts\shifts\node_modules\webpack\lib\NormalModuleFactory.js:776:25
<e>     at C:\dev\shifts\shifts\node_modules\webpack\lib\NormalModuleFactory.js:988:8
<e>     at C:\dev\shifts\shifts\node_modules\webpack\lib\NormalModuleFactory.js:1118:5
<e> resolve './Table' in 'C:\dev\shifts\shifts\src\pages\teamConfig\allocations'
<e>   using description file: C:\dev\shifts\shifts\package.json (relative path: ./src/pages/teamConfig/allocations)
<e>     Field 'browser' doesn't contain a valid alias configuration
<e>     using description file: C:\dev\shifts\shifts\package.json (relative path: ./src/pages/teamConfig/allocations/Table)
<e>       no extension
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table doesn't exist
<e>       .ts
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table.ts doesn't exist
<e>       .tsx
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table.tsx doesn't exist
<e>       .js
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table.js doesn't exist
<e>       as directory
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table doesn't exist
<e>       .tsx
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table.tsx doesn't exist
<e>       .js
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table.js doesn't exist
<e>       .tsx
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table.tsx doesn't exist
<e>       .js
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>       .tsx
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table.tsx doesn't exist
<e>       .js
<e>       .tsx
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>       .tsx
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>       .tsx
<e>       .tsx
<e>       .tsx
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table.tsx doesn't exist
<e>       .js
<e>         Field 'browser' doesn't contain a valid alias configuration
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table.js doesn't exist
<e>       as directory
<e>         C:\dev\shifts\shifts\src\pages\teamConfig\allocations\Table doesn't exist

Actual Behavior

Webpack-dev-server crashes when a file is renamed/deleted/moved etc. I'm not sure if this is a regression, but in a previous project it would throw an error in the console and the client but the server wouldn't crash.

Expected Behavior

It should throw an error saying the file is missing, but the server should continue to function without having to kill and restart.

How Do We Reproduce?

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "src",
    "target": "es2015",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "outDir": "dist",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": false, //need to emit as using fork-ts-checker-webpack-plugin
    "sourceMap": true,
    "jsx": "react-jsx"
  },
  "files": ["webpack.config.ts"],
  "include": [
    "src",
    "tests"  ],
  "ts-node": {
    "compilerOptions": {
      "module": "CommonJS"
    }
  }
}

webpack.config.ts:

import webpack from 'webpack'
import { relative, resolve } from 'path'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'
import TerserPlugin from 'terser-webpack-plugin'
import CopyWebpackPlugin from 'copy-webpack-plugin'
import ESLintPlugin from 'eslint-webpack-plugin'
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'
import ReactRefreshTypeScript from 'react-refresh-typescript'
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'
import getPublicUrlOrPath from 'react-dev-utils/getPublicUrlOrPath'
import { WebpackManifestPlugin } from 'webpack-manifest-plugin'

module.exports = (env: { APP_BUILD?: string; FUNCTION_APP?: string }) => {
  //get PUBLIC_URL, which is needed for production builds where process (which is a Node server var), doesn't exist
  const publicUrlOrPath = getPublicUrlOrPath(process.env.NODE_ENV === 'development', undefined, process.env.PUBLIC_URL)

  //set whether are creating source maps with prod builds
  const genSourceMaps: boolean = true

  const prod = process.env.NODE_ENV === 'production'

  return {
    mode: prod ? 'production' : 'development',
    cache: { type: 'filesystem' },
    infrastructureLogging: { level: 'info' },
    stats: 'normal',
    devtool: !prod ? (genSourceMaps ? 'source-map' : false) : false, 
    bail: true,
    resolve: {
      modules: [resolve(__dirname, 'node_modules'), resolve(__dirname, './src')]
    },
    entry: './src/index.tsx',
    output: {
      path: resolve(__dirname, 'build'),
      publicPath: publicUrlOrPath,
      filename: prod ? '[name].[contenthash:8].js' : undefined,
      chunkFilename: prod ? '[name].[contenthash:8].chunk.js' : undefined,
      assetModuleFilename: 'media/[name].[hash][ext]',
      clean: true, //clears the output dir prior to building

      // Point sourcemap entries to original disk location (format as URL on Windows)
      devtoolModuleFilenameTemplate: (info: any) => {
        if (prod) return relative('./src', info.absoluteResourcePath).replace(/\\/g, '/')
        else return resolve(info.absoluteResourcePath).replace(/\\/g, '/')
      }
    },
    devServer: {
      port: '3000',
      static: ['./public'],
      open: true,
      hot: true,
      historyApiFallback: true,
      client: {
        overlay: {
          errors: true,
          warnings: false,
          runtimeErrors: true
        },
        reconnect: 5 //TEST ONLY
      },
      devMiddleware: {
        publicPath: publicUrlOrPath,
        writeToDisk: true //massively speeds up loading of dev server
      }
    },
    module: {
      rules: [
        //Typescript loader
        //NOTE: uses fork-ts-checker-webpack-plugin for TS checking in dev on a separate thread
        {
          test: /\.([cm]?ts|tsx)$/,
          exclude: /node_modules/,
          resolve: {
            extensions: ['.ts', '.tsx', '.js']
          },

          use: [
            {
              loader: require.resolve('ts-loader'),
              options: {
                getCustomTransformers: () => ({
                  before: [!prod && ReactRefreshTypeScript()].filter(Boolean)
                }),
                transpileOnly: !prod
              }
            }
          ]
        },

        //CSS loaders
        {
          test: /\.css$/,
          exclude: /node_modules/,
          use: [
            //In prod, MiniCSSExtractPlugin extract CSS to file(s), but in development "style" loader enables hot editing of CSS.
            prod && MiniCssExtractPlugin.loader,

            //style loader turns CSS into JS modules that inject <style> tags
            !prod && require.resolve('style-loader'),

            //css-loader resolves paths in CSS and adds assets as dependencies
            {
              loader: require.resolve('css-loader'),
              options: { sourceMap: genSourceMaps }
            },

            //postcss loader applies autoprefixer to CSS
            {
              loader: require.resolve('postcss-loader'),
              options: { sourceMap: genSourceMaps }
            }
          ].filter(Boolean),
          sideEffects: true //See https://github.com/webpack/webpack/issues/6571
        }
      ].filter(Boolean)
    },
    plugins: [
      //Generates an `index.html` file with the <script> injected.
      new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html' }),

      //Copies the public directory into the root of build directory
      new CopyWebpackPlugin({ patterns: [{ from: 'public' }] }),

      //Makes environment variables available to the build code
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: JSON.stringify(process.env.NODE_ENV),
          PUBLIC_URL: JSON.stringify(publicUrlOrPath.slice(0, -1)),
          APP_BUILD: JSON.stringify(env.APP_BUILD),
          FUNCTION_APP: JSON.stringify(env.FUNCTION_APP)
        }
      }),

      ...(prod
        ? [
            //Extracts CSS into separate files
            new MiniCssExtractPlugin({
              filename: '[name].[contenthash:8].css',
              chunkFilename: '[name].[contenthash:8].chunk.css'
            }),

            // Generate an asset manifest file
            new WebpackManifestPlugin({
              fileName: 'asset-manifest.json',
              publicPath: publicUrlOrPath,
              generate: (seed, files, entrypoints) => {
                const manifestFiles = files.reduce((manifest, file) => {
                  manifest[file.name] = file.path
                  return manifest
                }, seed)

                const entrypointFiles = entrypoints.main.filter(fileName => !fileName.endsWith('.map'))

                return {
                  files: manifestFiles,
                  entrypoints: entrypointFiles
                }
              }
            })
          ]
        : []),

      ...(!prod
        ? [
            //Checks code for issues with eslint
            new ESLintPlugin({ extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'] }),

            //Enables new React hot reloading in dev builds
            new ReactRefreshWebpackPlugin(),

            //Used for TS checking - does the checks on a separate process to the build
            //NOTE: This plugin uses TypeScript's, not Webpack's modules resolution (i.e. uses tsconfig.json)
            new ForkTsCheckerWebpackPlugin()
          ]
        : [])
    ],
    optimization: {
      nodeEnv: false, //do not modify/set the value of process.env.NODE_ENV as this is done by DefinePlugin
      minimizer: [
        //minimise JS
        new TerserPlugin({
          extractComments: false,
          terserOptions: {
            format: {
              comments: false
            }
          }
        }),

        //minimise CSS
        new CssMinimizerPlugin()
      ]
    }
  }
}

Please paste the results of npx webpack-cli info here, and mention other relevant information

System:
OS: Windows 10 10.0.19045
CPU: (12) x64 12th Gen Intel(R) Core(TM) i7-1255U
Memory: 2.40 GB / 15.59 GB
Binaries:
Node: 20.11.1 - C:\Program Files\nodejs\node.EXE
npm: 10.2.4 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Chromium (127.0.2651.74)
Internet Explorer: 11.0.19041.4355
Packages:
copy-webpack-plugin: ^12.0.2 => 12.0.2
css-loader: ^7.1.1 => 7.1.2
css-minimizer-webpack-plugin: ^6.0.0 => 6.0.0
eslint-webpack-plugin: ^4.0.1 => 4.2.0
fork-ts-checker-webpack-plugin: ^9.0.0 => 9.0.2
html-webpack-plugin: ^5.5.1 => 5.6.0
postcss-loader: ^8.1.0 => 8.1.1
source-map-loader: ^5.0.0 => 5.0.0
style-loader: ^4.0.0 => 4.0.0
ts-loader: ^9.4.2 => 9.5.1
webpack: ^5.81.0 => 5.93.0
webpack-bundle-analyzer: ^4.9.0 => 4.10.2
webpack-cli: ^5.0.2 => 5.1.4
webpack-dev-server: ^5.0.4 => 5.0.4
webpack-manifest-plugin: ^5.0.0 => 5.0.0
workbox-webpack-plugin: ^7.0.0 => 7.1.0

@alexander-akait
Copy link
Member

Sounds like a duplicate of webpack/enhanced-resolve#395

@NathZ1
Copy link
Author

NathZ1 commented Aug 2, 2024

Hi @alexander-akait, thank you for your reply. I have reviewed the issue you linked, but I don't think it is the same issue. I am not using enhanced-resolve at all.

I have now created a small public repo where you can demo the issue -

https://github.com/NathZ1/webpack-dev-server-error-repo

Simply npm install, npm start, then rename the file 'src/FileToRename.tsx' and you should see the same webpack-dev-server crash as I am experiencing.

@alexander-akait
Copy link
Member

Don't use bail: true https://webpack.js.org/configuration/other-options/#bail, we have a tip about it. Bail stop any other compilations when the first error happend.

Avoid using bail option in watch mode, as it will force webpack to exit as soon as possible when an error is found.

@NathZ1
Copy link
Author

NathZ1 commented Aug 15, 2024

Ahh of course!! Apologies for taking up your time. Cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants