export default 本身不支持导出时重命名,需通过导入重命名+转移导出实现平滑迁移:保留原路径与接口契约,在壳文件中用 export { default as xxx } from './new.js' 或 export default from './new.js' 转发,默认导出必须来自目标模块的 default 导出。

直接用 export default 本身无法在导出时重命名——它没有名字,只允许在导入时自由命名。所谓“利用 export default 的重命名语法”实际是指:**通过导入时重命名 + 转移导出(re-export)组合,实现旧模块名不动、新逻辑渐进替换的平滑迁移**。
核心思路:不改调用方,只换被调用方
迁移不是重写所有 import 语句,而是让老代码仍能 import xxx from './old-module',但背后实际加载的是重构后的新模块。关键靠两层解耦:
- 保留原模块文件路径和默认导出结构(接口契约不变)
- 在该文件中用
export { default as xxx } from './new-logic.js'或export default from './new-logic.js'做转移导出
三步落地:从旧逻辑到新逻辑无感切换
1. 封装新逻辑为独立模块(带默认导出)
比如把原来散在 utils.js 里的订单校验逻辑,抽成新模块:
export default function validateOrder(order) {
return order.items?.length > 0 && order.total > 0;
}
2. 在原模块路径做“壳文件”,转移导出
保持 utils.js 文件存在,但内容改为:
export { default as validateOrder } from './order-validator-new.js';
// 或更简洁:
// export default from './order-validator-new.js';
3. 按需灰度切换,支持并行运行
若需逐步验证,可加运行时开关或环境判断:
// utils.jsimport LegacyValidator from './order-validator-legacy.js';
import NewValidator from './order-validator-new.js';
const useNew = process.env.NODE_ENV === 'production' && __NEW_VALIDATOR__; // 构建时注入
export default useNew ? NewValidator : LegacyValidator;
配合命名导出实现混合兼容
当旧模块既有默认导出,又有具名导出(如 export const helpers = {...}),迁移时可分层处理:
- 默认导出走转移:
export default from './new-main.js' - 具名导出保留或重导出:
export { helpers, formatError as format } from './legacy-utils.js' - 新增能力直接导出:
export const newFeature = () => {...}
这样调用方无需修改任何 import 语句,就能享受新逻辑,同时老功能照常可用。
注意事项:避免常见陷阱
- 转移导出的默认导出必须是另一个模块的
export default,不能是具名导出 - 不要在壳文件里再写业务逻辑——它只是路由,不是实现
- 确保新模块的输入/输出类型与旧版一致,否则调用方会报错(尤其 TypeScript 项目)
- 构建工具需支持 ESM 转移导出(Webpack 5+、Vite、esbuild 均支持)
这种模式本质是模块级的“适配器模式”,不碰业务代码,只动模块入口,适合中大型项目按模块渐进升级。










