Skip to content
This repository was archived by the owner on Jul 27, 2021. It is now read-only.

Commit 4218452

Browse files
christophehurpeaugeowarin
authored andcommitted
feat: group module not found errors (#31)
1 parent 1da743b commit 4218452

File tree

3 files changed

+103
-19
lines changed

3 files changed

+103
-19
lines changed

src/formatters/moduleNotFound.js

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,72 @@
11
'use strict';
22
const concat = require('../utils').concat;
33

4-
function dependenciesNotFound (count) {
4+
function moduleNotFound (count) {
55
if (count === 1) {
6-
return 'This dependency was not found in node_modules:';
6+
return 'This module was not found:';
77
}
88

9-
return 'These dependencies were not found in node_modules:';
9+
return 'These modules were not found:';
1010
}
1111

12-
function forgetToInstall (count) {
13-
if (count === 1) {
14-
return 'Did you forget to run npm install --save for it?';
12+
function forgetToInstall (missingDependencies) {
13+
const moduleNames = missingDependencies.map(missingDependency => missingDependency.module);
14+
15+
if (missingDependencies.length === 1) {
16+
return `To install it, you can run: npm install --save ${moduleNames.join(' ')}`;
1517
}
1618

17-
return 'Did you forget to run npm install --save for them?';
19+
return `To install them, you can run: npm install --save ${moduleNames.join(' ')}`;
20+
}
21+
22+
function isRelative (module) {
23+
return module.startsWith('./');
24+
}
25+
26+
function groupModules (errors) {
27+
const missingModule = new Map();
28+
29+
errors.forEach((error) => {
30+
if (!missingModule.has(error.module)) {
31+
missingModule.set(error.module, [])
32+
}
33+
missingModule.get(error.module).push(error);
34+
});
35+
36+
return Array.from(missingModule.keys()).map(module => ({
37+
module: module,
38+
relative: isRelative(module),
39+
errors: missingModule.get(module),
40+
}));
41+
}
42+
43+
function formatFileList (files) {
44+
const length = files.length;
45+
if (!length) return '';
46+
return ` in ${files[0]}${files[1] ? `, ${files[1]}` : ''}${length > 2 ? ` and ${length - 2} other${length === 3 ? '' : 's'}` : ''}`;
47+
}
48+
49+
function formatGroup (group) {
50+
const files = group.errors.map(e => e.file).filter(Boolean);
51+
return `* ${group.module}${formatFileList(files)}`;
1852
}
1953

2054
function formatErrors (errors) {
2155
if (errors.length === 0) {
2256
return [];
2357
}
2458

59+
const groups = groupModules(errors);
60+
const missingDependencies = groups.filter(group => !group.relative);
61+
2562
return concat(
26-
dependenciesNotFound(errors.length),
27-
'',
28-
errors.map(e =>`* ${e.module}${e.file ? ` in ${e.file}` : ''}`),
63+
moduleNotFound(errors.length),
2964
'',
30-
forgetToInstall(errors.length)
65+
groups.map(formatGroup),
66+
missingDependencies.length === 0 ? undefined : [
67+
'',
68+
forgetToInstall(missingDependencies)
69+
]
3170
);
3271
}
3372

test/integration.spec.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ it('integration : module-errors', async() => {
4747
expect(logs).toEqual([
4848
'ERROR Failed to compile with 2 errors',
4949
'',
50-
'These dependencies were not found in node_modules:',
50+
'These modules were not found:',
5151
'',
5252
'* ./non-existing in ./test/fixtures/module-errors/index.js',
5353
'* not-found in ./test/fixtures/module-errors/index.js',
5454
'',
55-
'Did you forget to run npm install --save for them?'
55+
'To install it, you can run: npm install --save not-found'
5656
]);
5757
});
5858

@@ -123,11 +123,11 @@ it('integration : webpack multi compiler : module-errors', async() => {
123123
expect(logs).toEqual([
124124
'ERROR Failed to compile with 2 errors',
125125
'',
126-
'These dependencies were not found in node_modules:',
126+
'These modules were not found:',
127127
'',
128128
'* ./non-existing in ./test/fixtures/multi-compiler-module-errors/index.js',
129129
'* not-found in ./test/fixtures/multi-compiler-module-errors/index2.js',
130130
'',
131-
'Did you forget to run npm install --save for them?'
131+
'To install it, you can run: npm install --save not-found'
132132
]);
133133
});

test/unit/formatters/moduleNotFound.spec.js

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,69 @@ const expect = require('expect');
44
it('Formats module-not-found errors', () => {
55
const error = { type: 'module-not-found', module: 'redux' };
66
expect(moduleNotFound([error])).toEqual([
7-
'This dependency was not found in node_modules:',
7+
'This module was not found:',
88
'',
99
'* redux',
1010
'',
11-
'Did you forget to run npm install --save for it?'
11+
'To install it, you can run: npm install --save redux'
1212
]);
1313
});
1414

1515
it('Groups all module-not-found into one', () => {
1616
const reduxError = { type: 'module-not-found', module: 'redux' };
1717
const reactError = { type: 'module-not-found', module: 'react' };
1818
expect(moduleNotFound([reduxError, reactError])).toEqual([
19-
'These dependencies were not found in node_modules:',
19+
'These modules were not found:',
2020
'',
2121
'* redux',
2222
'* react',
2323
'',
24-
'Did you forget to run npm install --save for them?'
24+
'To install them, you can run: npm install --save redux react'
25+
]);
26+
});
27+
28+
it('Groups same module in module-not-found with 2 files', () => {
29+
const reduxError = { type: 'module-not-found', module: 'redux' };
30+
const reactError1 = { type: 'module-not-found', module: 'react', file: './src/file1.js' };
31+
const reactError2 = { type: 'module-not-found', module: 'react', file: './src/file2.js' };
32+
expect(moduleNotFound([reduxError, reactError1, reactError2])).toEqual([
33+
'These modules were not found:',
34+
'',
35+
'* redux',
36+
'* react in ./src/file1.js, ./src/file2.js',
37+
'',
38+
'To install them, you can run: npm install --save redux react'
39+
]);
40+
});
41+
42+
it('Groups same module in module-not-found with 3 files', () => {
43+
const reduxError = { type: 'module-not-found', module: 'redux' };
44+
const reactError1 = { type: 'module-not-found', module: 'react', file: './src/file1.js' };
45+
const reactError2 = { type: 'module-not-found', module: 'react', file: './src/file2.js' };
46+
const reactError3 = { type: 'module-not-found', module: 'react', file: './src/file3.js' };
47+
expect(moduleNotFound([reduxError, reactError1, reactError2, reactError3])).toEqual([
48+
'These modules were not found:',
49+
'',
50+
'* redux',
51+
'* react in ./src/file1.js, ./src/file2.js and 1 other',
52+
'',
53+
'To install them, you can run: npm install --save redux react'
54+
]);
55+
});
56+
57+
it('Groups same module in module-not-found with 4 files', () => {
58+
const reduxError = { type: 'module-not-found', module: 'redux' };
59+
const reactError1 = { type: 'module-not-found', module: 'react', file: './src/file1.js' };
60+
const reactError2 = { type: 'module-not-found', module: 'react', file: './src/file2.js' };
61+
const reactError3 = { type: 'module-not-found', module: 'react', file: './src/file3.js' };
62+
const reactError4 = { type: 'module-not-found', module: 'react', file: './src/file4.js' };
63+
expect(moduleNotFound([reduxError, reactError1, reactError2, reactError3, reactError4])).toEqual([
64+
'These modules were not found:',
65+
'',
66+
'* redux',
67+
'* react in ./src/file1.js, ./src/file2.js and 2 others',
68+
'',
69+
'To install them, you can run: npm install --save redux react'
2570
]);
2671
});
2772

0 commit comments

Comments
 (0)