Skip to content

Commit

Permalink
fix: extract css in same order as imports (#295)
Browse files Browse the repository at this point in the history
  • Loading branch information
wardpeet committed Aug 24, 2020
1 parent c38f356 commit 2946eae
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 5 deletions.
32 changes: 30 additions & 2 deletions src/index.js
Expand Up @@ -15,6 +15,29 @@ function inferOption(option, defaultValue) {
return option ? {} : defaultValue
}

/**
* Recursivly get the correct import order from rollup
* We only process a file once
*
* @param {string} id
* @param {Function} getModuleInfo
* @param {Set<string>} seen
*/
function getRecursiveImportOrder(id, getModuleInfo, seen = new Set()) {
if (seen.has(id)) {
return []
}

seen.add(id)

const result = [id]
getModuleInfo(id).importedIds.forEach(importFile => {
result.push(...getRecursiveImportOrder(importFile, getModuleInfo, seen))
})

return result
}

export default (options = {}) => {
const filter = createFilter(options.include, options.exclude)
const postcssPlugins = Array.isArray(options.plugins) ?
Expand Down Expand Up @@ -149,10 +172,15 @@ export default (options = {}) => {

const concat = new Concat(true, fileName, '\n')
const entries = [...extracted.values()]
const { modules } = bundle[normalizePath(path.relative(dir, file))]
const { modules, facadeModuleId } = bundle[
normalizePath(path.relative(dir, file))
]

if (modules) {
const moduleIds = [...this.moduleIds]
const moduleIds = getRecursiveImportOrder(
facadeModuleId,
this.getModuleInfo
)
entries.sort(
(a, b) => moduleIds.indexOf(a.id) - moduleIds.indexOf(b.id)
)
Expand Down
60 changes: 60 additions & 0 deletions test/__snapshots__/index.test.js.snap
Expand Up @@ -195,6 +195,66 @@ console.log(undefined, undefined);
"
`;

exports[`extract nested: css code 1`] = `
"body {
color: red;
}
.bar-module_bar {
color: red;
}
a {
font-weight: bold;
}
.component-module_box {
color: blue;
}
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiLCJiYXIubW9kdWxlLmNzcyIsIm5lc3RlZC5jc3MiLCJjb21wb25lbnQubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLGlCQUFpQjtBQUNuQjs7QUNGQTtFQUNFLFdBQVc7QUFDYiIsImZpbGUiOiJidW5kbGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiYm9keSB7XG4gIGNvbG9yOiByZWQ7XG59XG4iLCIuYmFyIHtcbiAgY29sb3I6IHJlZDtcbn1cbiIsImEge1xuICBmb250LXdlaWdodDogYm9sZDtcbn1cbiIsIi5ib3gge1xuICBjb2xvcjogYmx1ZTtcbn0iXX0=*/"
`;

exports[`extract nested: js code 1`] = `
"'use strict';
var bar = {\\"bar\\":\\"bar-module_bar\\"};
var component = {\\"box\\":\\"component-module_box\\"};
console.log(bar, component);
"
`;

exports[`extract nested-delay-resolve: css code 1`] = `
"body {
color: red;
}
.bar-module_bar {
color: red;
}
a {
font-weight: bold;
}
.component-module_box {
color: blue;
}
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiLCJiYXIubW9kdWxlLmNzcyIsIm5lc3RlZC5jc3MiLCJjb21wb25lbnQubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLGlCQUFpQjtBQUNuQjs7QUNGQTtFQUNFLFdBQVc7QUFDYiIsImZpbGUiOiJidW5kbGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiYm9keSB7XG4gIGNvbG9yOiByZWQ7XG59XG4iLCIuYmFyIHtcbiAgY29sb3I6IHJlZDtcbn1cbiIsImEge1xuICBmb250LXdlaWdodDogYm9sZDtcbn1cbiIsIi5ib3gge1xuICBjb2xvcjogYmx1ZTtcbn0iXX0=*/"
`;

exports[`extract nested-delay-resolve: js code 1`] = `
"'use strict';
var bar = {\\"bar\\":\\"bar-module_bar\\"};
var component = {\\"box\\":\\"component-module_box\\"};
console.log(bar, component);
"
`;

exports[`extract relative-path: css code 1`] = `
"body {
color: red;
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/nested/bar.module.css
@@ -0,0 +1,3 @@
.bar {
color: red;
}
3 changes: 3 additions & 0 deletions test/fixtures/nested/component.js
@@ -0,0 +1,3 @@
import component from './component.module.css'

export default component
3 changes: 3 additions & 0 deletions test/fixtures/nested/component.module.css
@@ -0,0 +1,3 @@
.box {
color: blue;
}
3 changes: 3 additions & 0 deletions test/fixtures/nested/foo.css
@@ -0,0 +1,3 @@
body {
color: red;
}
6 changes: 6 additions & 0 deletions test/fixtures/nested/index.js
@@ -0,0 +1,6 @@
import './foo.css'
import bar from './bar.module.css'
import './nested'
import component from './component'

console.log(bar, component)
3 changes: 3 additions & 0 deletions test/fixtures/nested/nested.css
@@ -0,0 +1,3 @@
a {
font-weight: bold;
}
4 changes: 4 additions & 0 deletions test/fixtures/nested/nested.js
@@ -0,0 +1,4 @@
import './nested.css'

export default 'test'
export { default as component } from './component'
44 changes: 41 additions & 3 deletions test/index.test.js
Expand Up @@ -20,12 +20,33 @@ async function write({
outDir,
options
}) {
const { delayResolve, ...postCssOptions } = options

let first = true
// Delay the resolving of the first css file
const lateResolve = {
name: 'late-resolve',
async resolveId(importee) {
// when it's not a css file and not the first css file we return
if (!first || !importee.endsWith('.css')) {
return null
}

first = false

// delay resolving
return new Promise(resolve => {
setTimeout(() => resolve(null), 1000)
})
}
}

outDir = fixture('dist', outDir)
const bundle = await rollup({
input: fixture(input),
plugins: [
postcss(options)
]
plugins: [postcss(postCssOptions), delayResolve && lateResolve].filter(
Boolean
)
})
await bundle.write({
format: 'cjs',
Expand Down Expand Up @@ -295,6 +316,23 @@ snapshotMany('extract', [
sourceMap: 'inline',
extract: true
}
},
{
title: 'nested',
input: 'nested/index.js',
options: {
sourceMap: 'inline',
extract: true
}
},
{
title: 'nested-delay-resolve',
input: 'nested/index.js',
options: {
sourceMap: 'inline',
extract: true,
delayResolve: true
}
}
])

Expand Down

0 comments on commit 2946eae

Please sign in to comment.