mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 12:44:22 +00:00
fix(vite): bypass es-toolkit CJS shim for recharts deep imports
The Nodes page (and any other recharts-using route) crashed in dev and prod with TypeError: require_isUnsafeProperty is not a function. Root cause: es-toolkit's package.json exports './compat/*' only via a default condition pointing at the CJS shims under compat/<name>.js. Those shims use a require_X.Y access pattern that Vite's optimizer (Rolldown in Vite 8) and the production Rolldown build both mishandle, losing the named-export accessor and calling the namespace object as a function. recharts imports a dozen of these subpaths with default- import syntax, so every chart path tripped the bug. The matching ESM build at dist/compat/<category>/<name>.mjs is fine, but it only carries a named export. Recharts uses default imports. Plug a small Rollup-compatible plugin (enforce: 'pre') in front of the resolver: any 'es-toolkit/compat/<name>' request becomes a virtual module that imports the named symbol from the right .mjs file and re-exports it as both default and named. The plugin is registered as a top-level plugin (for the prod build) and via the new Vite 8 optimizeDeps.rolldownOptions.plugins (for the dev pre-bundler), so both pipelines pick it up consistently.
This commit is contained in:
parent
75b0a21987
commit
2d55b3b663
1 changed files with 45 additions and 1 deletions
|
|
@ -77,6 +77,45 @@ function injectBasePathPlugin() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// es-toolkit's `./compat/*` exports map only declares a CJS condition, so deep
|
||||||
|
// imports like `es-toolkit/compat/get` resolve to a CJS shim. That shim uses a
|
||||||
|
// `require_X.Y` pattern that Vite's optimizer and Rolldown both mishandle
|
||||||
|
// (TypeError: require_isUnsafeProperty is not a function). The ESM build at
|
||||||
|
// `dist/compat/<category>/<name>.mjs` is fine but only carries a named export,
|
||||||
|
// while consumers like recharts use default imports — so emit a virtual module
|
||||||
|
// that re-exports the named symbol as default.
|
||||||
|
const ES_TOOLKIT_COMPAT_DIRS = ['array', 'function', 'math', 'object', 'predicate', 'string', 'util'];
|
||||||
|
const ES_TOOLKIT_SHIM_PREFIX = '\0es-toolkit-compat:';
|
||||||
|
|
||||||
|
function findEsToolkitCompatMjs(name) {
|
||||||
|
for (const sub of ES_TOOLKIT_COMPAT_DIRS) {
|
||||||
|
const candidate = path.resolve(__dirname, 'node_modules/es-toolkit/dist/compat', sub, `${name}.mjs`);
|
||||||
|
if (fs.existsSync(candidate)) return candidate;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function esToolkitCompatEsmResolver() {
|
||||||
|
return {
|
||||||
|
name: 'es-toolkit-compat-esm',
|
||||||
|
enforce: 'pre',
|
||||||
|
resolveId(id) {
|
||||||
|
const m = id.match(/^es-toolkit\/compat\/(.+)$/);
|
||||||
|
if (!m) return null;
|
||||||
|
if (!findEsToolkitCompatMjs(m[1])) return null;
|
||||||
|
return ES_TOOLKIT_SHIM_PREFIX + m[1];
|
||||||
|
},
|
||||||
|
load(id) {
|
||||||
|
if (!id.startsWith(ES_TOOLKIT_SHIM_PREFIX)) return null;
|
||||||
|
const name = id.slice(ES_TOOLKIT_SHIM_PREFIX.length);
|
||||||
|
const target = findEsToolkitCompatMjs(name);
|
||||||
|
if (!target) return null;
|
||||||
|
const url = target.replace(/\\/g, '/');
|
||||||
|
return `import { ${name} } from ${JSON.stringify(url)};\nexport { ${name} };\nexport default ${name};\n`;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function bypassMigratedRoute(req) {
|
function bypassMigratedRoute(req) {
|
||||||
if (req.method !== 'GET') return undefined;
|
if (req.method !== 'GET') return undefined;
|
||||||
const url = req.url.split('?')[0];
|
const url = req.url.split('?')[0];
|
||||||
|
|
@ -140,12 +179,17 @@ function makeBackendProxy(target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), injectBasePathPlugin()],
|
plugins: [esToolkitCompatEsmResolver(), react(), injectBasePathPlugin()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve(__dirname, 'src'),
|
'@': path.resolve(__dirname, 'src'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
optimizeDeps: {
|
||||||
|
rolldownOptions: {
|
||||||
|
plugins: [esToolkitCompatEsmResolver()],
|
||||||
|
},
|
||||||
|
},
|
||||||
experimental: {
|
experimental: {
|
||||||
renderBuiltUrl(filename, { hostType }) {
|
renderBuiltUrl(filename, { hostType }) {
|
||||||
if (hostType === 'js') {
|
if (hostType === 'js') {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue