diff --git a/lib/loader.js b/lib/loader.js index cc807bb8..74b760fc 100644 --- a/lib/loader.js +++ b/lib/loader.js @@ -3,6 +3,7 @@ Author Tobias Koppers @sokra */ const postcss = require('postcss'); +const postcssPkg = require('postcss/package.json'); const localByDefault = require('postcss-modules-local-by-default'); const extractImports = require('postcss-modules-extract-imports'); const modulesScope = require('postcss-modules-scope'); @@ -26,7 +27,7 @@ const { const Warning = require('./Warning'); const CssSyntaxError = require('./CssSyntaxError'); -module.exports = function loader(content, map) { +module.exports = function loader(content, map, meta) { const callback = this.async(); const options = getOptions(this) || {}; const sourceMap = options.sourceMap || false; @@ -49,6 +50,16 @@ module.exports = function loader(content, map) { } /* eslint-enable no-param-reassign */ + // Reuse CSS AST (PostCSS AST e.g 'postcss-loader') to avoid reparsing + if (meta) { + const { ast } = meta; + + if (ast && ast.type === 'postcss' && ast.version === postcssPkg.version) { + // eslint-disable-next-line no-param-reassign + content = ast.root; + } + } + const resolveImport = options.import !== false; const resolveUrl = options.url !== false; const loaderContext = this; diff --git a/test/__snapshots__/loader.test.js.snap b/test/__snapshots__/loader.test.js.snap index 5b67d0fe..ee8c3dbb 100644 --- a/test/__snapshots__/loader.test.js.snap +++ b/test/__snapshots__/loader.test.js.snap @@ -444,9 +444,9 @@ You may need an appropriate loader to handle this file type. exports[`loader should throws error when no loader for assets: warnings 1`] = `Array []`; -exports[`loader using together with "postcss-loader": errors 1`] = `Array []`; +exports[`loader using together with "postcss-loader" and reuse \`ast\`: errors 1`] = `Array []`; -exports[`loader using together with "postcss-loader": module (evaluated) 1`] = ` +exports[`loader using together with "postcss-loader" and reuse \`ast\`: module (evaluated) 1`] = ` Array [ Array [ 1, @@ -513,7 +513,7 @@ a:hover { ] `; -exports[`loader using together with "postcss-loader": module 1`] = ` +exports[`loader using together with "postcss-loader" and reuse \`ast\`: module 1`] = ` "var escape = require(\\"../../../lib/runtime/escape.js\\"); exports = module.exports = require(\\"../../../lib/runtime/api.js\\")(false); // imports @@ -526,7 +526,7 @@ exports.push([module.id, \\":root {\\\\n --fontSize: 1rem;\\\\n --mainColor: r " `; -exports[`loader using together with "postcss-loader": warnings 1`] = `Array []`; +exports[`loader using together with "postcss-loader" and reuse \`ast\`: warnings 1`] = `Array []`; exports[`loader using together with "sass-loader": errors 1`] = `Array []`; diff --git a/test/loader.test.js b/test/loader.test.js index 98775de8..45ce7d7a 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -90,7 +90,8 @@ describe('loader', () => { expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors'); }); - it('using together with "postcss-loader"', async () => { + it('using together with "postcss-loader" and reuse `ast`', async () => { + // It is hard to test `postcss` on reuse `ast`, please look on coverage before merging const config = { postcssLoader: true, postcssLoaderOptions: {