web-ext icon indicating copy to clipboard operation
web-ext copied to clipboard

A reload now triggers infinite reloading in Chrome

Open ghostwords opened this issue 6 months ago • 11 comments

$ ./node_modules/.bin/web-ext --version
8.8.0
$ google-chrome --version
Google Chrome 138.0.7204.100 
$ ./node_modules/.bin/web-ext run --target chromium -s src/
Running web extension from /home/alexei/Projects/privacybadger/src
The extension will reload if any source file changes
Press R to reload (and Ctrl-C to quit)

I press R.

The extension reloads forever.

ghostwords avatar Jul 11 '25 20:07 ghostwords

Reload works with web-ext 8.6.0 and --arg="--disable-features=DisableLoadExtensionCommandLineSwitch" and manually "keeping" and re-enabling the reload manager extension. However the manual keep/re-enable is pretty annoying if you want to frequently relaunch for whatever reason. Also, DisableLoadExtensionCommandLineSwitch and manual re-enabling will both stop working at some point.

ghostwords avatar Jul 11 '25 20:07 ghostwords

I am unable to reproduce your problem. What I did in an attempt to reproduce is as follows:

  1. In a fresh Linux environment, I installed web-ext 8.8.0 and latest Chromium (138).
  2. I cloned https://github.com/EFForg/privacybadger (specific revision: https://github.com/EFForg/privacybadger/tree/6cfa4ccfc13ae26adf3a877acca3abdea24071cd)
  3. I tried running your command but it failed at first, with error: Error: Cannot install extension because it uses an unsupported manifest version.
  4. I tried again, now with: web-ext run -t chromium -s ~/privacybadger/src/ --arg=--enable-features=AllowLegacyMV2Extensions --verbose
  5. I pressed R.

Result: the extension reloaded once.

One potential cause of the infinite reload is if Chrome modifies the directory where the extension is loading from. I know that it does, for example, if it is a theme extension or an extension using declarativeNetRequest. For example, a simple extension with one static ruleset (even if disabled!) is compiled and written to _metadata/generated_indexed_rulesets/_ruleset1.

If you are getting tripped by auto-reload triggered by source changes, you could disable auto reloading by passing the --no-reload flag, and manually reload via chrome://extensions/ . Or if you do like the auto-reloading aspect but don't want to watch all directories, choose a specific file to watch by passing the --watch-file or --watch-files options to web-ext run

Rob--W avatar Jul 11 '25 20:07 Rob--W

Try reproducing with MV3 Privacy Badger: https://github.com/EFForg/privacybadger/tree/mv3-chrome

ghostwords avatar Jul 11 '25 21:07 ghostwords

Thank you for the workarounds! However, if it's indeed DNR, I don't think web-ext users with DNR extensions should individually have to discover and work around this problem.

ghostwords avatar Jul 11 '25 21:07 ghostwords

It is indeed DNR. If I check out your mv3-chrome branch and add --verbose, I see that web-ext detects changes to the file path I mentioned before and reloads Chrome as a result. This reload happens in all web-ext versions, not just the latest one. E.g. with [email protected] and the --verbose flags, I see that it detects the _metadata/ change I mentioned above and reloads the extension once.

With web-ext 8.6.0 the infinite-reload issue did not happen, because it did not re-install the extension (or even reload like what would happen if you pressed the Reload extension icon in chrome://extensions/ ), but it disabled and re-enabled the extension. With the latest web-ext version, the mechanism to reload extensions is the same as (re)installing an extension, which appears to trigger the full (DNR) initialization.

I'm supportive of ignoring the _metadata directory by default.

P.S. Ideally, Chrome should not change the source directory where it is loading from.

Rob--W avatar Jul 11 '25 21:07 Rob--W

Yeah agreed on all points (I don't like the _metadata directory either!), and thank you for the super quick response!!

ghostwords avatar Jul 11 '25 21:07 ghostwords

Btw, another option is to pass the --watch-ignored=/full/path/to/src/_metadata option (do not add a /).

The parameter will end up being passed to the watchpack library at https://github.com/mozilla/web-ext/blob/5ce29deea840f1c594971c345763025561de4711/src/watcher.js#L31

The option accepts a glob; paths if given must be absolute.

Rob--W avatar Jul 11 '25 21:07 Rob--W

With the latest web-ext version, the mechanism to reload extensions is the same as (re)installing an extension, which appears to trigger the full (DNR) initialization.

Does this mean something about the behavior of reloaded Chrome DNR extensions changed in the latest web-ext version? Does the new web-ext do reloading more correctly in some way (for DNR anyway)? Or is it just that more stuff happens on reload with latest web-ext but there is no difference in behavior?

ghostwords avatar Jul 11 '25 21:07 ghostwords

I discussed this issue with my team, and we are willing to unconditionally ignore the _metadata/ directory (at least when the target is chromium).

With the latest web-ext version, the mechanism to reload extensions is the same as (re)installing an extension, which appears to trigger the full (DNR) initialization.

Does this mean something about the behavior of reloaded Chrome DNR extensions changed in the latest web-ext version? Does the new web-ext do reloading more correctly in some way (for DNR anyway)?

Yes. A "reload" is now equivalent to issuing a request to install an extension in Chrome. Previously, it was disable and re-enable, for the lack of a better way to do so. If you'd like to learn more about the motivation and differences, see #3388 and #3434.

Rob--W avatar Jul 17 '25 15:07 Rob--W

If you'd like to learn more about the motivation and differences

Thanks, I looked at the linked issues, but I don't see an explanation of the differences between reloading with CDP and "reloading" via disable/enable w/ helper extension. If there are differences, it would be good to clearly document them somewhere, such as in the release notes or even just here in this issue.

ghostwords avatar Jul 17 '25 18:07 ghostwords

For anyone who finds this issue, it sounds like the main (only?) difference is that the manifest wasn't getting reloaded and now it is (#2277).

ghostwords avatar Jul 18 '25 14:07 ghostwords