Why Does Vite Need to Rewrite Pre-build Module Paths? 
The hook for rewriting imports is transformCjsImport, with the following source code comments:
/**
 * Detect import statements to a known optimized CJS dependency and provide
 * ES named imports interop. We do this by rewriting named imports to a variable
 * assignment to the corresponding property on the `module.exports` of the cjs
 * module. Note this doesn't support dynamic re-assignments from within the cjs
 * module.
 *
 * Note that es-module-lexer treats `export * from '...'` as an import as well,
 * so, we may encounter ExportAllDeclaration here, in which case `undefined`
 * will be returned.
 *
 * Credits \@csr632 via #837
 */The root of the problem is issue#837. Through tracing, we can find issue#720, which describes the error phenomenon when using named imports in Vite.
Chrome
## Uncaught SyntaxError: The requested module '/@modules/redux-dynamic-modules.js' does not provide an export named 'createStore'Firefox
## Uncaught SyntaxError: import not found: createStorePrerequisites 
- There are differences between importing - ESMand- CJSspecification modules.- In ESM: js- // index.js import demo from 'demo.js'; // demo.js export default { name: 'demo.js' }; export const name = 'demo.js';- The above code is compliant with the specification. js- // index.js import { name } from 'demo.js'; // demo.js export default { name: 'demo.js' }; export const p = 'demo.js';- The above code is not compliant with the specification. Named imports must correspond to named exports, meaning it must include: js- // index.js import { name } from 'demo.js'; // demo.js export const name = 'demo.js';- This meets the requirements. - In CJS: js- // index.js import { name } from 'demo.js'; // demo.js module.exports = { name: 'demo.js' };- The above code is compliant with the specification. 
- Typically, - Vitewill pre-build modules (usually CommonJS modules) that are either- Bare Importor configured in- config.optimizeDeps.include(CommonJS -> ESM).
With these two prerequisites, it's not difficult to understand the official comments. Simply put:
Since ESM will likely import pre-built products (CommonJS modules) in most cases, and these modules have already been bundled into ESM specification modules through Esbuild, it's no longer possible to import the default product through named imports.
/*======== origin ========*/
// index.js
import { name } from 'demo';
// demo.js
module.exports = {
  name: 'demo.js'
};
/*======== after bundle demo.js ========*/
error;
// index.js
import { name } from 'demo';
// demo.js
export default {
  name: 'demo.js'
};
success;
// index.js [rewrite path]
import uniqueName from 'demo';
const name = uniqueName.name;
// demo.js
export default {
  name: 'demo.js'
};How to Rewrite Pre-built Module Paths? 
In ESM, there are several import methods, so we only need to handle the following import methods:
// 1.
import React from 'react';
// 2.
import * as React from 'react';
// 3.
import { jsxDEV as _jsxDEV, Fragment } from 'react/jsx-dev-runtime';
// 4.
import('react');
// 5.
export { useState, useEffect as effect, useMemo as default } from 'react';
// 6.
export * as React from 'react';
// 7. Error!
export * from 'react';
// 8.
import 'react';- Rewrite default imports ( - import React from 'react'). For default imports, we mainly consider the- __esModuleproperty value in the CommonJS bundled product. If the value is- true, we take its- defaultvalue; if- false, we take its own value.js- // `const ${localName} = ${cjsModuleName}.__esModule ? ${cjsModuleName}.default : ${cjsModuleName}` import React from 'react'; // rewrite =============> import __vite__cjsImport0_react from '/node_modules/.vite/deps/react.js?v=048661c9'; const React = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react;- Why do we need the - __esModuleproperty?- Historical baggage: - Before the - ESMmodule specification was introduced, the- CommonJSmodule specification was commonly used.- Nodeis a typical example, natively supporting- CommonJS, so early libraries mostly supported- CommonJS(or AMD, etc.). Later, when the official promoted the- ESMmodularization solution, problems arose when mixing the two module formats.- ES modulesand- CommonJS modulesare not fully compatible, and- CommonJS's- module.exportshas no corresponding expression in- ES modules, which is different from default exports- export default. That is, in- ESM, you cannot use default imports for- CommonJS.js- // Bad Case: index.js import demo from './demo.js'; // Good Case: index.js import { name } from './demo.js'; import * as demo from './demo.js'; // demo.js module.exports = { name: 'demo' };- Solution: - The - __esModulesolution was first proposed by- Babel, and now build tools in the market have tacitly followed this convention. The convention is as follows:- Babelfirst introduces the- __esModuleidentifier in- CommonJSmodule files. If- __esModuleis- true, then when- CommonJSis converted to- ESM, the value exported by- export defaultis the value of- module.exports.default. If- __esModuleis- false, then when- CommonJSis converted to- ESM, the value of- export defaultis the value of the entire- module.exports. By following these rules, you can default import- CommonJSmodules in- ESM.js- exports.__esModule = true; // or Object.defineProperty(exports, '__esModule', { value: true });- Points to note: - If - __esModuleis- falsein a- CommonJSmodule, the entire- module.exportsobject is exported. If- __esModuleis set to- false, this object might have an extra- __esModuleproperty. Therefore, if- __esModuleis- false, it doesn't need to be set. It can be considered that- __esModuleis- falseby default.
- If - __esModuleis- truein a- CommonJSmodule but there is no- module.exports.defaultproperty. For this case, different build tools may have different behaviors.- In - ESbuild:js- //commonjs a.js module.exports.a = 2; module.exports.b = 3; module.exports.__esModule = true; //main.js import x from './a.js'; x = undefined;
- In - Vite:
 js- // `const ${localName} = ${cjsModuleName}.__esModule ? ${cjsModuleName}.default : ${cjsModuleName}` import React from 'react'; // rewrite =============> import __vite__cjsImport0_react from '/node_modules/.vite/deps/react.js?v=048661c9'; // React = undefined const React = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react;
- When importing in - .mjsfiles:
 js- //commonjs a.js module.exports.default = 'aa'; module.exports.a = 2; module.exports.b = 3; module.exports.__esModule = true; //main.mjs import x from './a.js'; x = { default: 'aa', a: 2, b: 2, __esModule: true };- Files ending with - .mjsare the form that supports- ESMin- nodejs. At this time, if you reference- CommonJSin files ending with- .mjs, it generally won't do special processing. The purpose of- __esModuleitself is to be compatible with the- nodejsenvironment, allowing- ESMto run in the- nodejsenvironment. Therefore,- __esModulewon't take effect here, and all properties are treated as ordinary properties.
- Rewrite - import * as React from 'react'. The rewriting method is similar to the first default export, but different in that- import *essentially needs to import all properties of the module, so there's no need to consider the- __esModuleproperty value.js- // const ${localName} = ${cjsModuleName} import * as React from 'react'; // rewrite =============> import __vite__cjsImport0_react from '/node_modules/.vite/deps/react.js?v=048661c9'; const React = __vite__cjsImport0_react;
- Rewrite named imports: js- // const ${localName} = ${cjsModuleName}["${importedName}"] import { jsxDEV as _jsxDEV, Fragment } from 'react/jsx-dev-runtime'; // rewrite =============> import __vite__cjsImport0_react_jsxDevRuntime from '/node_modules/.vite/deps/react_jsx-dev-runtime.js?v=65945471'; const _jsxDEV = __vite__cjsImport0_react_jsxDevRuntime.jsxDEV; const Fragment = __vite__cjsImport0_react_jsxDevRuntime.Fragment;
- Rewrite dynamic imports ( - import(...)) to directly expose the- defaultvalue.js- // import('${rewrittenUrl}').then(m => m.default && m.default.__esModule ? m.default : ({ ...m.default, default: m.default })) import('react'); // rewrite =============> import( '/node_modules/.vite/deps/react_jsx-dev-runtime.js?v=65945471' ).then(m => m.default && m.default.__esModule ? m.default : { ...m.default, default: m.default } );
- Rewrite re-exported modules, i.e., import then export. js- export { useState, useEffect as effect, useMemo as default } from 'react'; // rewrite =============> import __vite__cjsImport0_react from '/node_modules/.vite/deps/react.js?v=3c90f486'; const __vite__cjsExport_useState = __vite__cjsImport0_react.useState; const __vite__cjsExport_effect = __vite__cjsImport0_react.useEffect; const __vite__cjsExportDefault_0 = __vite__cjsImport0_react.useMemo; export default __vite__cjsExportDefault_0; export { __vite__cjsExport_useState as useState, __vite__cjsExport_effect as effect };
- Rewrite re-exported modules. js- export * as React from 'react'; // rewrite =============> export * as React from '/node_modules/.vite/deps/react.js?v=3c90f486';
- export * from 'react'has an error and may lose module exports. We can see this comment in the- transformCjsImportmethod:js- // `export * from '...'` may cause unexpected problem, so give it a warning if ( config.command === 'serve' && node.type === 'ExportAllDeclaration' && !node.exported ) { config.logger.warn( colors.yellow( `\nUnable to interop \`${importExp}\` in ${importer}, this may lose module exports. Please export "${rawUrl}" as ESM or use named exports instead, e.g. \`export { A, B } from "${rawUrl}"\`` ) ); }- So what causes this? We can trace back to this issue. Let's briefly explain the problem described in this issue: - Problem: In App.tsx, you cannot use named imports for re-exported content, but you can import normally through direct imports. js- // bug.ts export * from '@prisma/client';js- // App.tsx import { UserRole } from './bug.ts'; // Syntax error on runtime "The requested module bug.ts does not provide an export UserRole" import UserRole from './bug.ts'; // Syntax error on runtime "The requested module bug.ts does not provide an export named default" import { UserRole } from '@prisma/client'; // Works fine- Cause Analysis: - The export * from '@prisma/client'syntax means exporting all non-defaultdata collections from the@prisma/clientmodule, that is, usingexportto export inESM(notexport default).
- @prisma/clientis detected as a module that needs pre-building in- Vite(a CommonJS module). During the pre-build phase,- ESbuildwill build the original CommonJS module into an ESM module. By observing the build product, we can see that- ESbuild's build product of- CommonJSwill ultimately be exported as- export default. This means that- export * from 'CommonJS_Module'is meaningless (the build product won't export properties using- export). This explains why both- import { UserRole } from './bug.ts'and- import UserRole from "./bug.ts"report the same error. The former is because there is no- exportspecified- UserRoleproperty in- @prisma/client, and the latter is because- export * from 'xxx'exports non-- defaultdata collections. Both are empty property collections, so naturally, you can't get the- UserRoleand- defaultproperties.
- The reason why the third writing method works is that Vitedetermines@prisma/clientas a pre-built product, so it will rewrite the path:
 ts- import { UserRole } from '@prisma/client'; // rewrite ========> import __vite__cjsImport0_prisma_client from '/node_modules/.vite/deps/@prisma_client.js?v=65945471'; const UserRole = __vite__cjsImport0_prisma_client.UserRole;- /node_modules/.vite/deps/@prisma_client.js?v=65945471is the- ESMproduct already built by- Vite, exported by default using- export default, so it can execute successfully.
- The 
- import 'react'
import 'react';
// rewrite =============>
import '/node_modules/.vite/deps/react.js?v=3c90f486'; XiSenao
 XiSenao SenaoXi
 SenaoXi