Description
Problem description:
I noticed that using this plugin can result in invalid CSS being output when using @import
statements. Say there's a line @import url(blah);
in the input. This will be output as @import url(blah)
. Notice that the terminating semicolon is no longer present. This results in syntactically invalid CSS as this statement and the next one are no longer separated by the ;
terminator, causing web browsers to skip one (or both?) of them.
Cause:
I took a look at the source code:
Note that the first case matches only when a terminating semicolon is present, and that semicolon gets included. That match is later passed to parse-import
:
That module has dedicated logic (second line below) to strip away any trailing semicolon:
return imports.map(function (imp) {
imp = imp.replace(/(?:;)$/g, '');
return {
path: path(imp),
condition: condition(imp),
rule: imp
};
});
which is why it's stripped away in the final (now syntactically invalid) output.
Possible solution:
lib/css-replace.js
could be augmented as follows:
const parsed = parseImport(statement)
if (!parsed.length) {
throw new Error(`parse rule ${statement} failed`)
}
+ if (!parsed[0].rule.endsWith(';')) {
+ parsed[0].rule += ';'
+ }
+
/**
* parsed[0]: {
* path: 'foobar.css',
* condition: 'print',
- * rule: '@import url("foobar.css") print'
+ * rule: '@import url("foobar.css") print;'
* }
*/