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

watchContentBase watches for the first level only, ignoring deeper folders #1227

Closed
1 of 3 tasks
creage opened this issue Dec 13, 2017 · 12 comments
Closed
1 of 3 tasks

Comments

@creage
Copy link

creage commented Dec 13, 2017

  • Operating System: Windows 10
  • Node Version: 9.2.0
  • NPM Version: 5.5.1
  • webpack Version: 3.10.0
  • webpack-dev-server Version: 2.9.7
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js
...
devServer: {
    ...
    contentBase: DEST,
    watchContentBase: true,
    ...
}

Expected Behavior

Setting watchContentBase to true should watch contentBase paths all way deep

Actual Behavior

According to chockidar documentation, setting depth parameter limits the depth of folders being traversed, and the fix of #1208 limits it to 0, leading to changes in the deeper folders being ignored, and not triggering recompilation.

For Bugs; How can we reproduce the behavior?

  1. Place some folder with files and nested structure in the contentBase folder (folder1/folder2/file1.css)
  2. Start webpack-dev-server with watchContentBase: true
  3. Change file1.css from the structure created on step 1.
@shellscape
Copy link
Contributor

Unfortunately this isn't actually a bug in webpack-dev-server, but designed behavior. WDS uses chokidar and the options that WDS uses for chokidar mirror those found in watchpack, which is what webpack proper uses to watch files.

You'll notice that depth: 0, is defined in the options both here and in watchpack. That's expicitly to prevent complexity issues. Until watchpack, and by extension webpack, decides to change that value, we must keep it the same. You can try petition the folks running watchpack to allow that value to be changed, however.

@shellscape
Copy link
Contributor

@creage I'm not sure why you deleted your comment, but I'm happy to respond none-the-less.

@shellscape well, we've built our build process around this feature, and it was fine for around a year, and now it is removed, and you say it is as designed...
Is there any workaround to force webpack-dev-server to watch for nested changes of contentBase? I've tried to define my folders as array, but this does not work for some reason - changes still don't trig recompilation.

Unfortunately you built a solution around a bug that was subsequently fixed. If you'd like your use-case to be supported, bearing in mind that it's intentionally unsupported at the moment, the right path is to petition the watchpack module to allow overriding of the depth property to be set via options passed in. If it changes there, webpack-dev-server will quickly follow suit.

@creage
Copy link
Author

creage commented Dec 15, 2017

@shellscape after some deeper diving into the code, I understood, that this depth parameter has a great importance. The issue with it (if you don't limit it) is a huge amount of FS watchers, mostly redundant. Setting it to 0 ensures of watching root folder only.

So, I've ended up with writing my custom webpack plugin, which triggers a change event on root folder whenever some of my inner folders updated. Kinda event delegation. Nice approach, I like it more than multiple watchers.

@shellscape
Copy link
Contributor

@creage that's great news. please do share your plugin with the community!

@BiggAdd
Copy link

BiggAdd commented Feb 6, 2018

I don't think this person built their use-case around a bug, the documentation for watchContentBase states:

"Tell the server to watch the files served by the devServer.contentBase option. File changes will trigger a full page reload."

I would say that means all files within that folder. I think your fix for #1208 broke this feature. Either bug should be fixed or if this was genuinely an intended feature then the documentation needs to be updated.

@chasegiunta
Copy link

chasegiunta commented Mar 27, 2018

@creage would you mind sharing your webpack plugin? Also running into this.

@shellscape I believe that @BiggAdd has a valid point here — if only watching root for changes is the intended behavior, I believe the documentation needs to updated to reflect that

@shellscape

This comment has been minimized.

@creage
Copy link
Author

creage commented Mar 28, 2018

@chasegiunta well, the plugin code is really simple. The idea is every time some paths different then root are updated, I touch some file in the root, which triggers WDS to recompile.

const path = require('path'),
	fs = require('fs');
/**
 * Forces App to reload by touching index.html everytime module is recompiled
 */
class AppWatchPlugin {

	constructor(dest, file) {

		this.dest = dest;

		this.file = file || 'index.html';
	}

	apply(compiler) {
		compiler.plugin('done', () => {

			const currentDate = new Date(),
				fullPathOfFile = path.resolve(this.dest, this.file);

			fs.utimes(fullPathOfFile, currentDate, currentDate, err => {
				if (err) {
					console.log(err);
				}
			});
		});
	}
}

module.exports = AppWatchPlugin;

@alexander-akait
Copy link
Member

@creage FYI, not a good solution change atime and ctime, you can break cache for package which using this files.

@alexander-akait
Copy link
Member

Better example:

before(app, server) {
      const chokidar = require("chokidar");
      const files = [
        // Refreshing php files
        "**/*.php"
      ];

      chokidar
        .watch(files, {
          alwaysStat: true,
          atomic: false,
          followSymlinks: false,
          ignoreInitial: true,
          ignorePermissionErrors: true,
          ignored,
          persistent: true
        })
        .on("all", () => {
          server.sockWrite(server.sockets, "content-changed");
        });
    }

@chasegiunta
Copy link

chasegiunta commented Mar 29, 2018

Appreciate the time & answers to you both @evilebottnawi & @creage . I was really hopeful I could get one of your solutions to work.

@creage unfortunately, I can't seem to get the plugin to be called after saving a deeper folder.

@evilebottnawi Also tried your solution but ran into issues with globbing (chokidar doesn't seem to like / in the glob path, throws no parsers registered for: "]a(r)" errors)

I feel defeated! Any further suggestions you two have would be welcome 😅

** UPDATE **
Implemented https://github.com/amasad/sane in place of chokidar and it seems to work! 🎉Thanks again for both y'alls help.

@araphiel
Copy link

araphiel commented Oct 3, 2018

@evilebottnawi Thanks! Your solution worked perfectly in my use-case.

My webpack-dev-server + Jekyll setup -

edit: 🤦‍♂️ as it turns out, I didn't need the manual watchers for my use case at all.
contentBase was enough.... but the code still works.

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

6 participants