How to Resolve Export Format Conflicts Between ReScript and React Router v7 for Hot Module Replacement?

I export JavaScript files generated by ReScript in the format:

export {
  loader$1 as loader,
  make,
  $$default as default,
}

However, Hot Module Replacement in React Router v7 requires:

https://reactrouter.com/explanation/hot-module-replacement

export const headers = { "Cache-Control": "max-age=3600" }; // ✅
export const loader = async () => {}; // ✅
export const action = async () => {}; // ✅

What solution can address this issue?

@joshderochervlk got this working with react-router v7.
Maybe you can find some hints in this PR:

Thanks for your reply, but export {loader} won’t work in React Router, export const loader is required instead.

Hm, I believe this is not actually necessary.

At least it seems to work for me in the rescript-lang.org repo. I just changed something in the loader:
rescript-lang.org/app/routes/BlogRoute.res at master · rescript-lang/rescript-lang.org · GitHub
and it updated immediately in the browser.

So it seems you just need a .resi file for it to work?

Bear in mind we use .jsx everywhere in the docs repo, not sure if that makes a difference.

I used SSR, this appears to be related to SSR.
loader is server function.
Maybe caused by tree shaking?

It’s probably the alias when exporting.

You need to make sure somehow that loader is not renamed in the export object I think.

export {
  loader$1 as loader,
  make,
  $$default as default,
} 

This is the final output generated by Rescript.
When I changed the js file to export const loader = XXX, export default XXX
It started up normally when running in dev mode using the React Router CLI.

What does the code look like?

module Inner = {
  let loader = async () => Console.log("inner")
}

let loader = async () => Console.log("toplevel")

e.g. this compiles to

async function loader() {
  console.log("inner");
}

let Inner = {
  loader: loader
};

async function loader$1() {
  console.log("toplevel");
}

export {
  Inner,
  loader$1 as loader,
}

maybe you can restructure your code so that the compiler emits it without aliases. In the example above for instance by moving the Inner loader to a separate file.