Skip to content

Commit 2946eae

Browse files
authored
fix: extract css in same order as imports (#295)
1 parent c38f356 commit 2946eae

File tree

10 files changed

+156
-5
lines changed

10 files changed

+156
-5
lines changed

src/index.js

+30-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,29 @@ function inferOption(option, defaultValue) {
1515
return option ? {} : defaultValue
1616
}
1717

18+
/**
19+
* Recursivly get the correct import order from rollup
20+
* We only process a file once
21+
*
22+
* @param {string} id
23+
* @param {Function} getModuleInfo
24+
* @param {Set<string>} seen
25+
*/
26+
function getRecursiveImportOrder(id, getModuleInfo, seen = new Set()) {
27+
if (seen.has(id)) {
28+
return []
29+
}
30+
31+
seen.add(id)
32+
33+
const result = [id]
34+
getModuleInfo(id).importedIds.forEach(importFile => {
35+
result.push(...getRecursiveImportOrder(importFile, getModuleInfo, seen))
36+
})
37+
38+
return result
39+
}
40+
1841
export default (options = {}) => {
1942
const filter = createFilter(options.include, options.exclude)
2043
const postcssPlugins = Array.isArray(options.plugins) ?
@@ -149,10 +172,15 @@ export default (options = {}) => {
149172

150173
const concat = new Concat(true, fileName, '\n')
151174
const entries = [...extracted.values()]
152-
const { modules } = bundle[normalizePath(path.relative(dir, file))]
175+
const { modules, facadeModuleId } = bundle[
176+
normalizePath(path.relative(dir, file))
177+
]
153178

154179
if (modules) {
155-
const moduleIds = [...this.moduleIds]
180+
const moduleIds = getRecursiveImportOrder(
181+
facadeModuleId,
182+
this.getModuleInfo
183+
)
156184
entries.sort(
157185
(a, b) => moduleIds.indexOf(a.id) - moduleIds.indexOf(b.id)
158186
)

test/__snapshots__/index.test.js.snap

+60
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,66 @@ console.log(undefined, undefined);
195195
"
196196
`;
197197

198+
exports[`extract nested: css code 1`] = `
199+
"body {
200+
color: red;
201+
}
202+
203+
.bar-module_bar {
204+
color: red;
205+
}
206+
207+
a {
208+
font-weight: bold;
209+
}
210+
211+
.component-module_box {
212+
color: blue;
213+
}
214+
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiLCJiYXIubW9kdWxlLmNzcyIsIm5lc3RlZC5jc3MiLCJjb21wb25lbnQubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLGlCQUFpQjtBQUNuQjs7QUNGQTtFQUNFLFdBQVc7QUFDYiIsImZpbGUiOiJidW5kbGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiYm9keSB7XG4gIGNvbG9yOiByZWQ7XG59XG4iLCIuYmFyIHtcbiAgY29sb3I6IHJlZDtcbn1cbiIsImEge1xuICBmb250LXdlaWdodDogYm9sZDtcbn1cbiIsIi5ib3gge1xuICBjb2xvcjogYmx1ZTtcbn0iXX0=*/"
215+
`;
216+
217+
exports[`extract nested: js code 1`] = `
218+
"'use strict';
219+
220+
var bar = {\\"bar\\":\\"bar-module_bar\\"};
221+
222+
var component = {\\"box\\":\\"component-module_box\\"};
223+
224+
console.log(bar, component);
225+
"
226+
`;
227+
228+
exports[`extract nested-delay-resolve: css code 1`] = `
229+
"body {
230+
color: red;
231+
}
232+
233+
.bar-module_bar {
234+
color: red;
235+
}
236+
237+
a {
238+
font-weight: bold;
239+
}
240+
241+
.component-module_box {
242+
color: blue;
243+
}
244+
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiLCJiYXIubW9kdWxlLmNzcyIsIm5lc3RlZC5jc3MiLCJjb21wb25lbnQubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLGlCQUFpQjtBQUNuQjs7QUNGQTtFQUNFLFdBQVc7QUFDYiIsImZpbGUiOiJidW5kbGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiYm9keSB7XG4gIGNvbG9yOiByZWQ7XG59XG4iLCIuYmFyIHtcbiAgY29sb3I6IHJlZDtcbn1cbiIsImEge1xuICBmb250LXdlaWdodDogYm9sZDtcbn1cbiIsIi5ib3gge1xuICBjb2xvcjogYmx1ZTtcbn0iXX0=*/"
245+
`;
246+
247+
exports[`extract nested-delay-resolve: js code 1`] = `
248+
"'use strict';
249+
250+
var bar = {\\"bar\\":\\"bar-module_bar\\"};
251+
252+
var component = {\\"box\\":\\"component-module_box\\"};
253+
254+
console.log(bar, component);
255+
"
256+
`;
257+
198258
exports[`extract relative-path: css code 1`] = `
199259
"body {
200260
color: red;

test/fixtures/nested/bar.module.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.bar {
2+
color: red;
3+
}

test/fixtures/nested/component.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import component from './component.module.css'
2+
3+
export default component
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.box {
2+
color: blue;
3+
}

test/fixtures/nested/foo.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
color: red;
3+
}

test/fixtures/nested/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import './foo.css'
2+
import bar from './bar.module.css'
3+
import './nested'
4+
import component from './component'
5+
6+
console.log(bar, component)

test/fixtures/nested/nested.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
a {
2+
font-weight: bold;
3+
}

test/fixtures/nested/nested.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import './nested.css'
2+
3+
export default 'test'
4+
export { default as component } from './component'

test/index.test.js

+41-3
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,33 @@ async function write({
2020
outDir,
2121
options
2222
}) {
23+
const { delayResolve, ...postCssOptions } = options
24+
25+
let first = true
26+
// Delay the resolving of the first css file
27+
const lateResolve = {
28+
name: 'late-resolve',
29+
async resolveId(importee) {
30+
// when it's not a css file and not the first css file we return
31+
if (!first || !importee.endsWith('.css')) {
32+
return null
33+
}
34+
35+
first = false
36+
37+
// delay resolving
38+
return new Promise(resolve => {
39+
setTimeout(() => resolve(null), 1000)
40+
})
41+
}
42+
}
43+
2344
outDir = fixture('dist', outDir)
2445
const bundle = await rollup({
2546
input: fixture(input),
26-
plugins: [
27-
postcss(options)
28-
]
47+
plugins: [postcss(postCssOptions), delayResolve && lateResolve].filter(
48+
Boolean
49+
)
2950
})
3051
await bundle.write({
3152
format: 'cjs',
@@ -295,6 +316,23 @@ snapshotMany('extract', [
295316
sourceMap: 'inline',
296317
extract: true
297318
}
319+
},
320+
{
321+
title: 'nested',
322+
input: 'nested/index.js',
323+
options: {
324+
sourceMap: 'inline',
325+
extract: true
326+
}
327+
},
328+
{
329+
title: 'nested-delay-resolve',
330+
input: 'nested/index.js',
331+
options: {
332+
sourceMap: 'inline',
333+
extract: true,
334+
delayResolve: true
335+
}
298336
}
299337
])
300338

0 commit comments

Comments
 (0)