如何在Elm项目中使用openapi-generator生成的两个同名模块?
核心问题说明
Elm 不支持在同一个项目中引入两个包含同名模块的包,Elm 编译器要求所有可见模块的名称全局唯一,这是编译器的核心设计约束,没有绕过的方法。
可落地的解决方案
方案1:生成代码后执行批量重命名脚本
你可以在openapi-generator执行完成后,增加一步自动化后置处理脚本,批量替换所有生成的Elm文件中的模块声明、导入语句的前缀。比如给第一个微服务的生成代码统一加上ServiceA前缀,把所有module Api替换为module ServiceA.Api,import Api.Data替换为import ServiceA.Api.Data,第二个微服务统一加ServiceB前缀即可。
类Unix系统下可以直接用sed脚本实现,示例如下:# 处理服务A的Api模块 find ./generated/service-a -name "*.elm" -exec sed -i 's/^module Api/module ServiceA.Api/g' {} \; find ./generated/service-a -name "*.elm" -exec sed -i 's/^import Api/import ServiceA.Api/g' {} \; # 处理服务A的Api.Data模块 find ./generated/service-a -name "*.elm" -exec sed -i 's/^module Api.Data/module ServiceA.Api.Data/g' {} \; find ./generated/service-a -name "*.elm" -exec sed -i 's/^import Api.Data/import ServiceA.Api.Data/g' {} \;服务B的处理逻辑同理,将前缀替换为
ServiceB即可。该方案实现成本低,适合临时快速适配的场景。方案2:自定义openapi-generator的Elm生成模板
你可以将openapi-generator官方的Elm生成模板复制到本地项目目录,修改模板中固定写死的Api、Api.Data模块名,改为带动态参数的形式(比如{{servicePrefix}}.Api),生成时通过命令行参数传入不同服务的前缀值,同时指定使用你本地修改后的模板,这样生成出来的代码直接就带有区分度的模块前缀,无需后续修改。
该方案更适合长期维护的项目,后续只需要同步官方模板的更新内容即可,不需要反复调整替换脚本。方案3:拆分生成代码为独立私有包
如果两个微服务的API变动频率较低,你可以把每个服务的生成代码分别做成独立的Elm私有包,修改完模块前缀后存放到私有包源,主项目分别引入两个带有不同模块前缀的包即可。该方案适合多项目需要共用同一份API生成代码的场景。
内容的提问来源于stack exchange,提问作者Matthias Wimmer

