如何自动将项目中800余个Ngrx旧Action改写为Action Group?
将Ngrx旧版独立Action批量转换为Action Group的方法
旧版Action示例
export const GetAction = createAction( '[BOOK] GET', props<{ filter: BookFilterModel, }>(), ); export const GetFailAction = createAction( '[BOOK] GET_FAIL', ); export const GetSuccessAction = createAction( '[BOOK] GET_SUCCESS', props<{ book: BookModel, }>(), );
可行的批量转换方法
1. Ngrx官方迁移工具
Ngrx内置了schematics迁移工具,可自动将旧版独立Action转换为Action Group。确保项目已安装@ngrx/schematics,终端运行以下命令:
ng generate @ngrx/schematics:migrate action-groups
该命令会扫描项目中所有createAction定义的独立Action,自动按Action类型前缀(如[BOOK])分组,重构为对应的Action Group类。
2. 自定义TypeScript AST脚本
如果官方工具无法覆盖特殊场景,可使用ts-morph这类AST处理工具编写自定义转换脚本,精准控制转换逻辑:
- 遍历项目中所有Action定义文件
- 识别每个
createAction调用,提取Action类型字符串、参数props信息 - 按前缀分组(如
[BOOK]),生成对应的Action Group类 - 替换原有独立Action定义
示例简化逻辑代码:
import { Project, SyntaxKind } from 'ts-morph'; const project = new Project(); project.addSourceFilesAtPaths('src/**/*.actions.ts'); project.getSourceFiles().forEach(sourceFile => { // 提取所有createAction定义的Action节点 const actionNodes = sourceFile.getVariableDeclarations().filter(decl => decl.getInitializer()?.getKind() === SyntaxKind.CallExpression && (decl.getInitializer() as any).getExpression().getText() === 'createAction' ); // 按前缀分组Action const actionGroups: Record<string, any[]> = {}; actionNodes.forEach(node => { const actionTypeArg = (node.getInitializer() as any).getArguments()[0].getText(); const prefix = actionTypeArg.match(/^\[(\w+)\]/)[1]; if (!actionGroups[prefix]) actionGroups[prefix] = []; actionGroups[prefix].push({ name: node.getName().replace('Action', ''), type: actionTypeArg, props: (node.getInitializer() as any).getArguments()[1]?.getText() }); }); // 生成Action Group类 Object.entries(actionGroups).forEach(([prefix, actions]) => { const className = `${prefix}Actions`; const classDeclaration = sourceFile.addClass({ name: className, isExported: true, }); actions.forEach(action => { classDeclaration.addMethod({ name: action.name.toLowerCase(), isStatic: true, returnType: `Action`, bodyText: `return createAction(${action.type}${action.props ? `, ${action.props}` : ''});` }); }); // 删除原有独立Action定义 actionNodes.forEach(node => node.remove()); }); sourceFile.save(); });
3. IDE正则批量替换
对于命名规则统一的Action(如XxxAction、XxxFailAction、XxxSuccessAction),可借助IDE的正则替换功能批量处理:
- 匹配同一组的所有Action定义
- 替换为Action Group类的成员方法
示例正则(以IntelliJ系IDE为例):
查找模式:
export const (\w+)Action = createAction\( '\[BOOK\] (\w+)', (props<\{[^}]+\}>)?\);
替换模式:
static $1() { return createAction('[BOOK] $2'$3); }
替换后手动补充Action Group的类定义,将方法包裹其中。
内容的提问来源于stack exchange,提问作者Dmitriy Ivanko
相关产品推荐
相关产品推荐

