UNPKG

1.6 kBJavaScriptView Raw
1import postcss from 'postcss';
2
3/**
4 * Get the number of selectors for a given node.
5 * @param {Object} node CSS node in question.
6 * @returns {Number} Total number of selectors associated with that node.
7 */
8const getSelLength = (node) => {
9 if (node.type === 'rule') {
10 return node.selectors.length;
11 }
12 if (node.type === 'atrule') {
13 return 1 + node.nodes.reduce((memo, n) => {
14 return memo + getSelLength(n);
15 }, 0);
16 }
17 return 0;
18};
19
20/**
21 * PostCSS plugin that splits the generated result into multiple results based
22 * on number of selectors.
23 * @param {Number} size Maximum number of rules in a single file.
24 * @param {Function} result Options passed to `postcss.toResult()`
25 * @returns {Object} `postcss` plugin instance.
26 */
27export default postcss.plugin('postcss-chunk', ({
28 size = 4000,
29 result: genResult = () => {
30 return {};
31 },
32} = {}) => {
33 return (css, result) => {
34 const chunks = [];
35 let count;
36 let chunk;
37
38 // Create a new chunk that holds current result.
39 const nextChunk = () => {
40 count = 0;
41 chunk = css.clone({nodes: []});
42 chunks.push(chunk);
43 };
44
45 // Walk the nodes. When we overflow the selector count, then start a new
46 // chunk. Collect the nodes into the current chunk.
47 css.nodes.forEach((n) => {
48 const selCount = getSelLength(n);
49 if (!chunk || count + selCount > size) {
50 nextChunk();
51 }
52 chunk.nodes.push(n);
53 count += selCount;
54 });
55
56 // Output the results.
57 result.chunks = chunks.map((c, i) => {
58 return c.toResult(genResult(i, c));
59 });
60 };
61});