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

NODE: revalidate() doesn't refresh module when a file has been changed and remoteEntry.js is the same. #843

Closed
pedrokehl opened this issue May 3, 2023 · 6 comments

Comments

@pedrokehl
Copy link
Contributor

pedrokehl commented May 3, 2023

Opening another issue since the previous one got closed without a resolution: #366

Issue

  • Given the app exposing Federated Modules depends on some JavaScript file (from an NPM package or internal)
  • When the JavaScript file on the project that is exposing the Federated Modules is changed and deployed
  • Then the projects that are using the Federated Modules are NOT being refreshed, and revalidate() is returning false.

Reason

The hashing strategy for the revalidate is based solely on the response of remoteEntry.js (or whatever filename you defined in your webpack config), as seen here, so if another internal module of the project changes, the revalidate for these modules won't detect it as changed.

There's no hashes representing the imported files in the generated remoteEntry.js file, so the hash in the revalidate won't detect anything.

Example

Minimal example with the issue:
https://github.com/pedrokehl/module-federation-nodejs-example

Instructions

Start app2: cd app2 / npm start
Start app1: cd app1 / npm start
Before the interval finishes, change the file app2/mapBook.js
Restart app2
shouldReload2 is false, and content is not updated

@pedrokehl pedrokehl changed the title Revalidate doesn't refresh when an internal/external module is changed and remoteEntry.js is the same. NODE: Revalidate doesn't refresh when an internal/external module is changed and remoteEntry.js is the same. May 3, 2023
@pedrokehl pedrokehl changed the title NODE: Revalidate doesn't refresh when an internal/external module is changed and remoteEntry.js is the same. NODE: revalidate() doesn't refresh module when a file has been changed and remoteEntry.js is the same. May 3, 2023
@ScriptedAlchemy
Copy link
Member

remote hashing should work though. Since all chunks are content hashed, so any change to a module = new chunk hash = detectable change to remote.

Are you using [contenthash] on your chunks?

the other option here is i can adjust the plugin slightly and add some runtime module / comment to the remote container that basically acts like a timestamp, every deploy would have a new hash then, always, even if no change exists

@brunocabral88
Copy link
Contributor

I came here to raise an issue but I'm glad I found this one already here :)
I can confirm @ScriptedAlchemy's suggestion (to use [contenthash]) works perfectly fine, as it slightly changes the remoteEntry.js file to point to the new hashed chunk, causing the revalidate to detect the changes. 🎉

I will submit a PR to include this detail in the revalidate documentation on https://www.npmjs.com/package/@module-federation/node.

brunocabral88 added a commit to brunocabral88/universe that referenced this issue May 29, 2023
Added more details to the revalidate documentation as the default webpack configuration, which does not hash development chunks, may cause the revalidate method not to work as developers expect.

Motivation: module-federation#843
@stevebrowndotco
Copy link

Had exactly the same issue. With nextJs, I solved this problem by prepending all of our SSR remoteEntry.js files with a timestamp, for each federated module. Physically in the file, and not with webpack. I achieved this by running a node script on the pipeline after the nextjs build. That was the only way for us to get revalidate working. This is similar to what @ScriptedAlchemy suggests above, but since I'm not sure how to update the plugin without understanding the MF internal code, this was the approach I opted for.

@beratbayram this approach might help you ^^^

edit: nodeJs pipeline script that fixed it for me:

const fs = require('fs');

const filePath = process.argv[2];
const timestamp = Date.now();
const content = `//Timestamp: ${timestamp}\n`;

fs.readFile(filePath, 'utf8', (err, data) => {
    if (err) {
        console.error(`Error reading file: ${err}`);
        return;
    }

    const updatedContent = content + data;

    fs.writeFile(filePath, updatedContent, err => {
        if (err) {
            console.error(`Error writing file: ${err}`);
            return;
        }

Docker:

RUN node update-timestamp.js /app/dist/apps/${APP_NAME}/.next/static/ssr/remoteEntry.js

@ScriptedAlchemy
Copy link
Member

this is a little hacky, but absolutely plausible workaround.

Im likely a week or two away from releasing the v7 plugin interation, and ill ensure theres a solid hashing/busting solution cooked directly into the webpack runtime. in v7 i have my own runtime modules so we can easily write something like this into the remote without patching the asset after the fact (one way i did it before was more or less a webpack plugin equivalent of the code you have demoed)

if youre open to testing out the new major release, its on npm under the "next" tag - this is a major rewrite with almost all the code thrown out and rebuilt. getting some feedback ahead of making v7 the stable release would be helpful as its a large change.

most of the requests im holding to implement in v7 - one unknown is the backward compatibility or interop between 6 and 7.

ScriptedAlchemy pushed a commit that referenced this issue Jun 30, 2023
Added more details to the revalidate documentation as the default webpack configuration, which does not hash development chunks, may cause the revalidate method not to work as developers expect.

Motivation: #843
RussellCanfield pushed a commit to RussellCanfield/nextjs-mf that referenced this issue Jul 1, 2023
Added more details to the revalidate documentation as the default webpack configuration, which does not hash development chunks, may cause the revalidate method not to work as developers expect.

Motivation: module-federation#843
@beratbayram
Copy link

I should add that with my SSR-less workaround below there is no problem anymore. In root it still requires a manual page refresh but it is clean and errorless.

#1102 (comment)

RussellCanfield pushed a commit to RussellCanfield/nextjs-mf that referenced this issue Aug 26, 2023
Added more details to the revalidate documentation as the default webpack configuration, which does not hash development chunks, may cause the revalidate method not to work as developers expect.

Motivation: module-federation#843
@github-actions
Copy link
Contributor

Stale issue message

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

No branches or pull requests

5 participants