Skip to content

Duplicate imports are resolved in the wrong order #462

Closed
@evanw

Description

@evanw

This plugin uses a different import order than the browser, which can lead to visual discrepancies when CSS is bundled vs. unbundled. I believe this is a regression and that it was caused by #211. The behavior used to be correct but was broken in that change, and is now incorrect.

Here's an example (note that the file common.css is being imported twice):

$ cat common.css
body { background: white; color: black; }

$ cat a.css
@import "./common.css";
body { background: red; }

$ cat b.css
@import "./common.css";
body { color: red; }

$ cat entry.css
@import "./a.css";
@import "./b.css";

$ cat index.html
<link rel="stylesheet" href="entry.css">
Some example text

When you view index.html in a browser, you should see a white background and red text. However, when bundled with PostCSS, the entire page is red.

Here's the script I used to bundle with PostCSS:

const css = require('fs').readFileSync('entry.css', 'utf8')
require('postcss')().use(require('postcss-import')({
})).process(css, {
  from: 'entry.css',
}).then(result => {
  console.log(result.css)
})

The incorrect behavior can be "fixed" by adding skipDuplicates: false to the postcss-import options, but that's not great because it makes the output bigger unnecessarily. This option is also dangerous because skipDuplicates: false can cause postcss-import to infinite-loop and hang if the import graph has cycles.

The way to fix all of these problems and have postcss-import match what the browser does is to only respect the last duplicate @import statement instead of only respecting the first duplicate @import statement.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions