Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webpack watch mode with CopyWebpackPlugin causes infinite loop

In webpack, CopyWebpackPlugin causes infinite loop when webpack is in watch mode. I tried to add watchOptions.ignored option but it doesn't seem to work. My webpack config is following:

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const config = {

    entry: {
        'res': './src/index.js'
    },
    output: {
        filename: '[name].min.js',
        path: path.resolve(__dirname, 'dist')
    },
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['es2015']
                    }
                }
            }
        ]
    },

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

        new CopyWebpackPlugin([
            { from: 'dist', to: path.resolve(__dirname, 'docs/js') }
        ], {})
    ],

    watchOptions: {
        ignored: path.resolve(__dirname, 'docs/js')
    }
};

module.exports = config;

Any help would be appreciated.

like image 428
Miriam Zusin Avatar asked May 07 '26 10:05

Miriam Zusin


2 Answers

So I know this question is very old at this point, but I was running into this endless loop issue again recently and found a couple of solutions.

  1. Not the cleanest method, but if you add an "assets" folder, which can be completely empty, to the root of your project, it seems to only compile after your sources folder changes.
  2. The better method I have found is within the webpack config. The original poster mentioned about using ignored which does seem to fix the issue if you instruct webpack to watch file changes after the initial build and to ignore your dist/output folder...

module.exports = {
  //...
  watch: true,
  watchOptions: {
    ignored: ['**/dist/**', '**/node_modules'],
  },
};
like image 187
Gareth Arch Avatar answered May 09 '26 03:05

Gareth Arch


I also had this same problem.

I first tried the solution below with the wathOptions.ignored setting in the root of the webpack config.

watchOptions: {
    ignored: ['**/node_modules'],
}

This however felt like a "nuclear" solution. With some extra investigation I found a more clean fix for this:

  1. create a webpack plugin to print the modified files which are the trigger for the watch to trigger, this code originates from the stackoverflow: https://stackoverflow.com/a/64564708:
    class WatchRunPlugin {
        apply(compiler) {
            compiler.hooks.watchRun.tap('WatchRun', (comp) => {
                if (comp.modifiedFiles) {
                    const changedFiles = Array.from(comp.modifiedFiles, (file) => `\n  ${file}`).join('');
                    console.log('===============================');
                    console.log('FILES CHANGED:', changedFiles);
                    console.log('===============================');
                }
            });
        }
    }
    
  2. use this plugin in your webpack config, add it to the list of plugins
  3. start a build watch and reproduce the infinite loop
  4. look at the FILES CHANGED message to identify the files causing the infinite loop
  5. fix this issue: for me, these were files originating from an npm package in the node_modules folder, these were added to the CopyWebpackPlugin with a glob pattern (*). By replacing the glob pattern by the actual file names, the issue was resolved.
like image 26
sdec Avatar answered May 09 '26 03:05

sdec