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

Incorrect JavaScript configuration caching behavior #16234

Open
MeanderingProgrammer opened this issue Apr 26, 2024 · 0 comments
Open

Incorrect JavaScript configuration caching behavior #16234

MeanderingProgrammer opened this issue Apr 26, 2024 · 0 comments

Comments

@MeanderingProgrammer
Copy link

MeanderingProgrammer commented Apr 26, 2024

Environments:

  • Prettier Version: 3.2.5
  • Running Prettier via: prettierd
  • Runtime: Node.js v20
  • Operating System: macOS
  • Prettier plugins (if any): N/A

Steps to reproduce:

  1. Create prettier.config.js with some initial settings
  2. Format via prettierd
  3. Modify prettier.config.js
  4. Format again via prettierd

Expected behavior:

Code is formatted with settings from latest configuration.

Actual behavior:

Configuration changes are ignored and code is formatted with previous settings.

Details:

prettierd is a plugin that keeps prettier as a long lived process and calls format on running instances.

It first pulls the configuration using resolveConfig then calls format with this configuration.

However, despite using the useCache: false setting to pickup any changes to the configuration, when the configuration is written in JavaScript changes do not get picked up.

From looking at the code to load a JavaScript configuration I think the issue stems from this function: https://github.com/prettier/prettier/blob/main/src/config/prettier-config/loaders.js#L20

async function loadJs(file) {
  const module = await import(pathToFileURL(file).href);
  return module.default;
}

Which uses import to load the configuration associated with the file.

However import itself has a cache within Node. Though I'm not too familiar with the details of import caching I believe this will result in the same response until the process is restarted. I've created a similar issue in prettierd to see if there is some way around this on the client side: fsouza/prettierd#719.

There really doesn't seem to be a good way to handle reloading a module via an import statement in JavaScript. I implemented and tested a "functional" solution locally based on some discussion from here: nodejs/node#49442.

async function loadJs(file) {
  const modulePath = `${pathToFileURL(file).href}?version=${Math.random()}`;
  const module = await import(modulePath);
  return module.default;
}

It relies on some odd behavior where the query part of the path doesn't change what actually gets imported, but will cause a cache miss so Node will reload the module.

This has its own drawbacks such as memory leaking, while old "versions" will not be retrieved, since they are still referenced in some internal cache they never get cleaned up. As well as just being very unintuitive.

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

1 participant