Skip to content

Commit 4bdf08b

Browse files
fix: emit warnings on broken @import (#806)
BREAKING CHANGE: invalid `@import` at rules now emit warnings
1 parent 8f0232b commit 4bdf08b

7 files changed

+102
-10
lines changed

lib/Warning.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module.exports = class Warning extends Error {
2+
constructor(warning) {
3+
super(warning);
4+
const { text, line, column } = warning;
5+
this.name = 'Warning';
6+
7+
// Based on https://github.com/postcss/postcss/blob/master/lib/warning.es6#L74
8+
// We don't need `plugin` properties.
9+
this.message = `${this.name}\n\n`;
10+
11+
if (typeof line !== 'undefined') {
12+
this.message += `(${line}:${column}) `;
13+
}
14+
15+
this.message += `${text}`;
16+
17+
// We don't need stack https://github.com/postcss/postcss/blob/master/docs/guidelines/runner.md#31-dont-show-js-stack-for-csssyntaxerror
18+
this.stack = false;
19+
}
20+
};

lib/postcss-css-loader-parser.js

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ module.exports = postcss.plugin(
6363
}
6464

6565
if (!url.replace(/\s/g, '').length) {
66+
result.warn(`Unable to find uri in '${atrule.toString()}'`, {
67+
node: atrule,
68+
});
69+
6670
return;
6771
}
6872

lib/processCss.js

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const modulesValues = require('postcss-modules-values');
1212

1313
const cssLoaderParser = require('./postcss-css-loader-parser');
1414

15+
const Warning = require('./Warning');
1516
const CssSyntaxError = require('./CssSyntaxError');
1617
const { getLocalIdent } = require('./utils');
1718

@@ -83,6 +84,12 @@ module.exports = function processCss(inputSource, inputMap, options, callback) {
8384
: null,
8485
})
8586
.then((result) => {
87+
result
88+
.warnings()
89+
.forEach((warning) =>
90+
options.loaderContext.emitWarning(new Warning(warning))
91+
);
92+
8693
callback(null, {
8794
source: result.css,
8895
map: result.map && result.map.toJSON(),

test/__snapshots__/import-option.test.js.snap

+61-1
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,64 @@ exports.push([module.id, \\"@import URL(test.css);\\\\n@import url();\\\\n@impor
240240
"
241241
`;
242242

243-
exports[`import option true: warnings 1`] = `Array []`;
243+
exports[`import option true: warnings 1`] = `
244+
Array [
245+
"ModuleWarning: Module Warning (from \`replaced original path\`):
246+
Warning
247+
248+
(12:1) Unable to find uri in '@import url()'",
249+
"ModuleWarning: Module Warning (from \`replaced original path\`):
250+
Warning
251+
252+
(13:1) Unable to find uri in '@import url('')'",
253+
"ModuleWarning: Module Warning (from \`replaced original path\`):
254+
Warning
255+
256+
(14:1) Unable to find uri in '@import url(\\"\\")'",
257+
"ModuleWarning: Module Warning (from \`replaced original path\`):
258+
Warning
259+
260+
(17:1) Unable to find uri in '@import '''",
261+
"ModuleWarning: Module Warning (from \`replaced original path\`):
262+
Warning
263+
264+
(18:1) Unable to find uri in '@import \\"\\"'",
265+
"ModuleWarning: Module Warning (from \`replaced original path\`):
266+
Warning
267+
268+
(19:1) Unable to find uri in '@import \\" \\"'",
269+
"ModuleWarning: Module Warning (from \`replaced original path\`):
270+
Warning
271+
272+
(20:1) Unable to find uri in '@import \\"
273+
\\"'",
274+
"ModuleWarning: Module Warning (from \`replaced original path\`):
275+
Warning
276+
277+
(22:1) Unable to find uri in '@import url()'",
278+
"ModuleWarning: Module Warning (from \`replaced original path\`):
279+
Warning
280+
281+
(23:1) Unable to find uri in '@import url('')'",
282+
"ModuleWarning: Module Warning (from \`replaced original path\`):
283+
Warning
284+
285+
(24:1) Unable to find uri in '@import url(\\"\\")'",
286+
"ModuleWarning: Module Warning (from \`replaced original path\`):
287+
Warning
288+
289+
(37:1) Unable to find uri in '@import '",
290+
"ModuleWarning: Module Warning (from \`replaced original path\`):
291+
Warning
292+
293+
(38:1) Unable to find uri in '@import foo-bar'",
294+
"ModuleWarning: Module Warning (from \`replaced original path\`):
295+
Warning
296+
297+
(40:1) It looks like you didn't end your @import statement correctly. Child nodes are attached to it.",
298+
"ModuleWarning: Module Warning (from \`replaced original path\`):
299+
Warning
300+
301+
(5:1) Unable to find uri in '@import URL(test.css)'",
302+
]
303+
`;

test/__snapshots__/loader.test.js.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ exports[`loader should compile with empty css entry point: warnings 1`] = `Array
392392

393393
exports[`loader should throw error on invalid css syntax: errors 1`] = `
394394
Array [
395-
[ModuleBuildError: Module build failed (from \`replaced original path\`):
395+
"ModuleBuildError: Module build failed (from \`replaced original path\`):
396396
CssSyntaxError
397397
398398
(2:3) Unknown word
@@ -402,7 +402,7 @@ CssSyntaxError
402402
| ^
403403
3 | }
404404
4 |
405-
],
405+
",
406406
]
407407
`;
408408

test/helpers.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,11 @@ exports.evaluated = evaluated;
308308

309309
function normalizeErrors(errors) {
310310
return errors.map((error) => {
311-
// eslint-disable-next-line no-param-reassign
312-
error.message = stripAnsi(error.message)
311+
const message = error.toString();
312+
313+
return stripAnsi(message)
313314
.replace(/\(from .*?\)/, '(from `replaced original path`)')
314315
.replace(/at(.*?)\(.*?\)/g, 'at$1(`replaced original path`)');
315-
316-
return error;
317316
});
318317
}
319318

test/import-option.test.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { webpack, evaluated } = require('./helpers');
1+
const { webpack, evaluated, normalizeErrors } = require('./helpers');
22

33
describe('import option', () => {
44
it('true', async () => {
@@ -11,8 +11,10 @@ describe('import option', () => {
1111
expect(evaluated(module.source, modules)).toMatchSnapshot(
1212
'module (evaluated)'
1313
);
14-
expect(stats.compilation.warnings).toMatchSnapshot('warnings');
15-
expect(stats.compilation.errors).toMatchSnapshot('errors');
14+
expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot(
15+
'warnings'
16+
);
17+
expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors');
1618
});
1719

1820
it('false', async () => {

0 commit comments

Comments
 (0)