ES Modules 通过路径组织、命名约定和显式导入导出自然支撑分层结构,典型三层为:Core层(基础能力)、Domain层(领域逻辑)、App层(组合调度),配合路径别名、入口收敛与循环依赖规避策略保障可维护性。

ES Modules 本身不强制分层,但通过文件路径组织、命名约定和 import/export 的显式声明,可以自然支撑清晰的模块分层结构。关键在于用目录层级表达职责边界,再靠静态导入关系固化依赖流向。
核心分层结构与职责划分
大型项目通常按稳定性和复用性从底向上划分为三层:
-
Core 层(基础能力):封装与业务无关的通用逻辑,如请求封装、工具函数、类型定义、全局配置。导出内容应稳定、无副作用,例如:
src/core/api.js导出统一的request()函数;src/core/utils/date.js导出formatDate()和isSameDay() -
Domain 层(领域逻辑):按业务域切分,每个子目录代表一个高内聚功能单元,如
user、order、payment。每个域内部可进一步拆为api/、store/、types/、hooks/等子模块,对外只暴露明确的入口文件(如index.js) -
App 层(组合与调度):位于最上层,负责初始化、路由挂载、状态注入、跨域协调。它只 import domain 和 core 模块,绝不反向依赖;典型文件是
src/app.js或src/main.js
路径别名与可维护导入
避免深层嵌套导致的冗长相对路径(如 ../../../core/utils/string.js),推荐在构建工具中配置路径别名:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- Webpack 中使用
resolve.alias:把@core映射到src/core,@domain/user映射到src/domains/user - Vite 中通过
resolve.alias同样支持,且开发时热更新更稳定 - 导入示例:
import { request } from '@core/api';、import { useUserStore } from '@domain/user/store';
入口收敛与模块边界控制
每个 domain 目录下设 index.js 作为唯一公共出口,集中 re-export 内部能力,隐藏实现细节:
立即学习“Java免费学习笔记(深入)”;
-
src/domains/cart/index.js可写:export { default as CartProvider } from './CartProvider';export { useCart } from './store';export * as cartApi from './api'; - 上层模块只 import 这个
index.js,不直接引用子路径,便于未来重构内部结构而不影响调用方
避免循环依赖的实际做法
当两个 domain 模块需要互相调用时,不要让它们直接 import 彼此,而是提取共用逻辑到 core 层,或引入专用的 shared/ 子目录:
- 例如 user 和 order 都需校验手机号,就把
validatePhone()放到src/core/validators.js,双方都从这里导入 - 若必须跨域触发行为(如“下单成功后更新用户积分”),采用事件总线或状态订阅机制,而非硬依赖

















