I tried writing a vite transformation plugin to enable code written in ReScript to run properly in SSR mode with React Router v7 in Vite. However, I still haven’t found the reason why it doesn’t support the error caused by export { someVariable as default } .
But it seems to be working properly now.
// vite-plugin-fix-dollar-default-export.js
export default function fixDollarDefaultExport() {
return {
name: 'fix-dollar-default-export',
transform(code, id) {
if (!/\.(js|jsx|ts|tsx|mjs|cjs)$/.test(id)) return null;
let transformedCode = code;
let hasChanged = false;
const exportBlockPattern = /export\s*\{([^}]+)\}/g;
const exportBlocks = [...transformedCode.matchAll(exportBlockPattern)];
for (const block of exportBlocks) {
const fullMatch = block[0];
const exportContent = block[1].trim();
if (exportContent.includes('as default')) {
const exportItems = exportContent.split(',')
.map(item => item.trim())
.filter(item => item.length > 0);
const defaultExports = [];
const normalExports = [];
for (const item of exportItems) {
const asDefaultMatch = item.match(/^(.+?)\s+as\s+default$/);
if (asDefaultMatch) {
const varName = asDefaultMatch[1].trim();
if (/^[\w$]+$/.test(varName)) {
defaultExports.push(varName);
} else {
normalExports.push(item);
}
} else {
normalExports.push(item);
}
}
if (defaultExports.length > 0) {
let newExports = '';
if (normalExports.length > 0) {
newExports += `export { ${normalExports.join(', ')} };\n`;
}
defaultExports.forEach(varName => {
newExports += `export default ${varName};\n`;
});
console.log('origin: ', transformedCode)
transformedCode = transformedCode.replace(fullMatch, () => newExports.trim());
console.log(fullMatch + ' ---> ' + newExports.trim())
console.log("result: ", transformedCode)
hasChanged = true;
}
}
}
if (hasChanged) {
return {
code: transformedCode,
map: null
};
}
return null;
}
};
}
// vite.config.js
import { reactRouter } from "@react-router/dev/vite";
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";
import rewrite from './vite-plugin-fix-export-default'
export default defineConfig({
plugins: [tailwindcss(), rewrite(), reactRouter(), ]
});
input
origin: // Generated by ReScript, PLEASE EDIT WITH CARE
import * as JsxRuntime from "react/jsx-runtime";
function loader() {
return Promise.resolve({
text: "about 1"
});
}
function About$default(props) {
return JsxRuntime.jsx("strong", {
children: props.loaderData.text
});
}
let $$default = About$default;
export {
loader,
$$default as default,
}
/* react/jsx-runtime Not a pure module */
output:
result: // Generated by ReScript, PLEASE EDIT WITH CARE
import * as JsxRuntime from "react/jsx-runtime";
function loader() {
return Promise.resolve({
text: "about 1"
});
}
function About$default(props) {
return JsxRuntime.jsx("strong", {
children: props.loaderData.text
});
}
let $$default = About$default;
export { loader };
export default $$default;
/* react/jsx-runtime Not a pure module */
Translation target:
export {
loader,
$$default as default,
} ---> export { loader };
export default $$default;