实现“单向隔离”导出需通过模块边界、显式导出控制、接口抽象三层设计,仅暴露无副作用的纯接口,禁用默认导出,统一经顶层api.ts封装,配合TS类型约束与构建时静态分析确保契约一致性。

要实现复杂业务逻辑的“单向隔离”导出,核心不是单纯用 export 暴露功能,而是通过模块边界 + 显式导出控制 + 接口抽象三层设计,让外部只能按约定调用,无法反向依赖内部实现细节。
只导出稳定契约,不导出实现路径
业务逻辑常含状态管理、副作用调用、私有工具函数等,这些都不该被导出。应仅暴露经过封装的、无副作用的纯接口函数或类实例方法。
- 避免直接导出内部类构造器或状态变量:如
export class OrderProcessor { ... }容易被外部 new 实例并篡改状态 - 改为导出工厂函数或单例实例:
export const orderService = new OrderService();或export function createOrderService(config) { ... } - 对关键入参做类型/结构校验,拒绝非法输入,从入口切断误用可能
用命名导出明确语义,禁用默认导出
默认导出(export default)容易导致使用者随意重命名、掩盖真实意图,削弱契约感;命名导出强制使用一致标识符,利于代码审查与自动化管控。
- 导出项全部采用有意义的驼峰名,如
export const validateOrderInput、export const submitOrderFlow - 禁止
export default,哪怕只有一个主函数——它会模糊“这是能力接口”还是“这是实现主体”的界限 - 配合 TypeScript 的
declare module或 JSDoc @public 标记,进一步约束可访问范围
通过 re-export 构建逻辑门禁
在业务模块顶层,不直接导出底层 service 或 utils,而是统一经由一个 index.ts(或 api.ts)文件做二次筛选和包装,形成“导出防火墙”。
- 底层模块保持高内聚:如
./core/validator.ts、./adapters/payment.ts全部不对外暴露 - 顶层
api.ts只写:export { validateOrderInput } from './core/validator';,且可加中间转换层:export const submitOrder = wrapWithLogging(submitOrderRaw); - 构建时启用
noImplicitAny和noUnusedExports,自动剔除未声明使用的导出项
结合构建时静态分析强化隔离
仅靠语法无法阻止运行时反射或动态访问,需配合工具链建立“导出即承诺”的工程纪律。
- 用 ESLint 插件如
import/no-unused-modules检测未被导入的导出项,及时清理冗余出口 - 在 CI 中加入模块图分析(如
depcheck或自定义 AST 扫描),识别跨域调用:例如payment模块被reporting模块 import,但未在payment/api.ts中显式导出,即视为违规 - 生成导出清单文档(JSON 格式),供架构评审与下游 SDK 封装使用,确保所有导出都有明确用途和生命周期标注

















