@@ -2,6 +2,8 @@ import { getOptions } from 'loader-utils';
22import validateOptions from 'schema-utils' ;
33
44import postcss from 'postcss' ;
5+ import { satisfies } from 'semver' ;
6+ import postcssPackage from 'postcss/package.json' ;
57
68import Warning from './Warning' ;
79import SyntaxError from './Error' ;
@@ -23,11 +25,12 @@ import {
2325 *
2426 * @param {String } content Source
2527 * @param {Object } sourceMap Source Map
28+ * @param {Object } meta Meta
2629 *
2730 * @return {callback } callback Result
2831 */
2932
30- export default async function loader ( content , sourceMap ) {
33+ export default async function loader ( content , sourceMap , meta ) {
3134 const options = getOptions ( this ) ;
3235
3336 validateOptions ( schema , options , {
@@ -65,11 +68,6 @@ export default async function loader(content, sourceMap) {
6568 options . postcssOptions
6669 ) ;
6770
68- if ( options . execute ) {
69- // eslint-disable-next-line no-param-reassign
70- content = exec ( content , this ) ;
71- }
72-
7371 if ( useSourceMap ) {
7472 processOptions . map = { inline : false , annotation : false } ;
7573
@@ -84,10 +82,27 @@ export default async function loader(content, sourceMap) {
8482 processOptions . map . prev = sourceMap ;
8583 }
8684
85+ let root ;
86+
87+ // Reuse PostCSS AST from other loaders
88+ if (
89+ meta &&
90+ meta . ast &&
91+ meta . ast . type === 'postcss' &&
92+ satisfies ( meta . ast . version , `^${ postcssPackage . version } ` )
93+ ) {
94+ ( { root } = meta . ast ) ;
95+ }
96+
97+ if ( ! root && options . execute ) {
98+ // eslint-disable-next-line no-param-reassign
99+ content = exec ( content , this ) ;
100+ }
101+
87102 let result ;
88103
89104 try {
90- result = await postcss ( plugins ) . process ( content , processOptions ) ;
105+ result = await postcss ( plugins ) . process ( root || content , processOptions ) ;
91106 } catch ( error ) {
92107 if ( error . file ) {
93108 this . addDependency ( error . file ) ;
0 commit comments