diff --git a/src/lib/expandApplyAtRules.js b/src/lib/expandApplyAtRules.js index 561343266945..ce8108e0697e 100644 --- a/src/lib/expandApplyAtRules.js +++ b/src/lib/expandApplyAtRules.js @@ -122,6 +122,27 @@ function processApply(root, context) { // Fill up some caches! let applyClassCache = buildApplyCache(applyCandidates, context) + // Collect all classes for @apply rules. + root.walk((node) => { + if (node.selector && node.selector[0] === '.') { + const name = node.selector.substring(1) + + // Ignore unused candidates. + if (applyCandidates.has(name) && !applyClassCache.has(name)) { + applyClassCache.set(name, [ + [ + { + sort: BigInt(context.layerOrder.user), + layer: 'user', + options: {}, + }, + node, + ], + ]) + } + } + }) + /** * When we have an apply like this: * diff --git a/tests/apply.test.js b/tests/apply.test.js index b4932a702c40..c5b4b5f3b092 100644 --- a/tests/apply.test.js +++ b/tests/apply.test.js @@ -616,3 +616,40 @@ it('rules with vendor prefixes are still separate when optimizing defaults rules `) }) }) + +it('should pickup all classes', () => { + let config = { + content: [{ raw: html`
` }], + plugins: [], + } + + let input = css` + .bop { + color: red; + } + + .bar { + background-color: blue; + } + + .foo { + @apply absolute bar bop; + } + ` + + return run(input, config).then((result) => { + return expect(result.css).toMatchFormattedCss(css` + .bop { + color: red; + } + .bar { + background-color: blue; + } + .foo { + position: absolute; + background-color: blue; + color: red; + } + `) + }) +})