Skip to content

Commit c38e634

Browse files
Keen Yee Liauhansl
authored andcommitted
refactor(@schematics/angular): Parameterize findModule
This commit modifies `findModule` to accept custom regular expressions so that a different filename convention for Angular modules is allowed.
1 parent 813c520 commit c38e634

File tree

2 files changed

+79
-19
lines changed

2 files changed

+79
-19
lines changed

packages/schematics/angular/utility/find-module.ts

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ export interface ModuleOptions {
1515
flat?: boolean;
1616
path?: string;
1717
skipImport?: boolean;
18+
moduleExt?: string;
19+
routingModuleExt?: string;
1820
}
1921

22+
const MODULE_EXT = '.module.ts';
23+
const ROUTING_MODULE_EXT = '-routing.module.ts';
2024

2125
/**
2226
* Find the module referred by a set of options passed to the schematics.
@@ -26,44 +30,46 @@ export function findModuleFromOptions(host: Tree, options: ModuleOptions): Path
2630
return undefined;
2731
}
2832

33+
const moduleExt = options.moduleExt || MODULE_EXT;
34+
const routingModuleExt = options.routingModuleExt || ROUTING_MODULE_EXT;
35+
2936
if (!options.module) {
3037
const pathToCheck = (options.path || '')
3138
+ (options.flat ? '' : '/' + strings.dasherize(options.name));
3239

33-
return normalize(findModule(host, pathToCheck));
40+
return normalize(findModule(host, pathToCheck, moduleExt, routingModuleExt));
3441
} else {
3542
const modulePath = normalize(
3643
'/' + (options.path) + '/' + options.module);
3744
const moduleBaseName = normalize(modulePath).split('/').pop();
3845

39-
if (host.exists(modulePath)) {
40-
return normalize(modulePath);
41-
} else if (host.exists(modulePath + '.ts')) {
42-
return normalize(modulePath + '.ts');
43-
} else if (host.exists(modulePath + '.module.ts')) {
44-
return normalize(modulePath + '.module.ts');
45-
} else if (host.exists(modulePath + '/' + moduleBaseName + '.module.ts')) {
46-
return normalize(modulePath + '/' + moduleBaseName + '.module.ts');
47-
} else {
48-
throw new Error('Specified module does not exist');
46+
const candidates = [
47+
modulePath,
48+
`${modulePath}.ts`,
49+
`${modulePath}${moduleExt}`,
50+
`${modulePath}/${moduleBaseName}${moduleExt}`,
51+
];
52+
for (const c of candidates) {
53+
if (host.exists(c)) {
54+
return normalize(c);
55+
}
4956
}
57+
throw new Error(`Specified module '${options.module}' does not exist.`);
5058
}
5159
}
5260

5361
/**
5462
* Function to find the "closest" module to a generated file's path.
5563
*/
56-
export function findModule(host: Tree, generateDir: string): Path {
57-
let dir: DirEntry | null = host.getDir('/' + generateDir);
58-
59-
const moduleRe = /\.module\.ts$/;
60-
const routingModuleRe = /-routing\.module\.ts/;
64+
export function findModule(host: Tree, generateDir: string,
65+
moduleExt = MODULE_EXT, routingModuleExt = ROUTING_MODULE_EXT): Path {
6166

67+
let dir: DirEntry | null = host.getDir('/' + generateDir);
6268
let foundRoutingModule = false;
6369

6470
while (dir) {
65-
const allMatches = dir.subfiles.filter(p => moduleRe.test(p));
66-
const filteredMatches = allMatches.filter(p => !routingModuleRe.test(p));
71+
const allMatches = dir.subfiles.filter(p => p.endsWith(moduleExt));
72+
const filteredMatches = allMatches.filter(p => !p.endsWith(routingModuleExt));
6773

6874
foundRoutingModule = foundRoutingModule || allMatches.length !== filteredMatches.length;
6975

@@ -78,7 +84,7 @@ export function findModule(host: Tree, generateDir: string): Path {
7884
}
7985

8086
const errorMsg = foundRoutingModule ? 'Could not find a non Routing NgModule.'
81-
+ '\nModules with suffix \'-routing.module\' are strictly reserved for routing.'
87+
+ `\nModules with suffix '${routingModuleExt}' are strictly reserved for routing.`
8288
+ '\nUse the skip-import option to skip importing in NgModule.'
8389
: 'Could not find an NgModule. Use the skip-import option to skip importing in NgModule.';
8490

packages/schematics/angular/utility/find-module_spec.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,25 @@ describe('find-module', () => {
7474
expect(err.message).toMatch(/Could not find an NgModule/);
7575
}
7676
});
77+
78+
it('should accept custom ext for module', () => {
79+
const host = new EmptyTree();
80+
const modulePath = '/foo/src/app/app_module.ts';
81+
host.create(modulePath, 'app module');
82+
// Should find module if given a custom ext
83+
const foundModule = findModule(host, 'foo/src/app/bar', '_module.ts');
84+
expect(foundModule).toBe(modulePath);
85+
// Should not find module if using default ext
86+
expect(() => findModule(host, 'foo/src/app/bar'))
87+
.toThrowError(/Could not find an NgModule/);
88+
});
89+
90+
it('should not find module if ext is invalid', () => {
91+
expect(() => findModule(host, 'foo/src/app/bar', '-module.ts'))
92+
.toThrowError(/Could not find an NgModule/);
93+
expect(() => findModule(host, 'foo/src/app/bar', '_module.ts'))
94+
.toThrowError(/Could not find an NgModule/);
95+
});
7796
});
7897

7998
describe('findModuleFromOptions', () => {
@@ -100,5 +119,40 @@ describe('find-module', () => {
100119
const modPath = findModuleFromOptions(tree, options);
101120
expect(modPath).toEqual('/projects/my-proj/src/admin/foo.module.ts' as Path);
102121
});
122+
123+
it('should find a module using custom ext', () => {
124+
tree.create('/projects/my-proj/src/app_module.ts', '');
125+
options.module = 'app';
126+
options.path = '/projects/my-proj/src';
127+
options.moduleExt = '_module.ts';
128+
// Should find module using custom moduleExt
129+
const modPath = findModuleFromOptions(tree, options);
130+
expect(modPath).toBe('/projects/my-proj/src/app_module.ts' as Path);
131+
// Should not find module if using invalid ext
132+
options.moduleExt = '-module.ts';
133+
expect(() => findModuleFromOptions(tree, options)).toThrowError(
134+
/Specified module 'app' does not exist/);
135+
// Should not find module if using default ext
136+
options.moduleExt = undefined; // use default ext
137+
expect(() => findModuleFromOptions(tree, options)).toThrowError(
138+
/Specified module 'app' does not exist/);
139+
});
140+
141+
it('should ignore custom ext if module or ${module}.ts exists', () => {
142+
tree.create('/projects/my-proj/src/app.module.ts', '');
143+
options.path = '/projects/my-proj/src';
144+
options.moduleExt = '_module.ts';
145+
let modPath;
146+
147+
// moduleExt ignored because exact path is found
148+
options.module = 'app.module.ts';
149+
modPath = findModuleFromOptions(tree, options);
150+
expect(modPath).toBe('/projects/my-proj/src/app.module.ts' as Path);
151+
152+
// moduleExt ignored because module + .ts is found
153+
options.module = 'app.module';
154+
modPath = findModuleFromOptions(tree, options);
155+
expect(modPath).toBe('/projects/my-proj/src/app.module.ts' as Path);
156+
});
103157
});
104158
});

0 commit comments

Comments
 (0)