diff --git a/index.js b/index.js index c8c20f08..bde8ba07 100644 --- a/index.js +++ b/index.js @@ -275,10 +275,20 @@ module.exports = { * * https://github.com/postcss/postcss-loader * + * Encore.enablePostCssLoader(); + * + * Or pass options to the loader + * + * Encore.enablePostCssLoader(function(options) { + * // https://github.com/postcss/postcss-loader#options + * // options.config = {...} + * }) + * + * @param {function} postCssLoaderOptionsCallback * @return {exports} */ - enablePostCssLoader() { - webpackConfig.enablePostCssLoader(); + enablePostCssLoader(postCssLoaderOptionsCallback = () => {}) { + webpackConfig.enablePostCssLoader(postCssLoaderOptionsCallback); return this; }, diff --git a/lib/WebpackConfig.js b/lib/WebpackConfig.js index 40173d3f..c229a9e0 100644 --- a/lib/WebpackConfig.js +++ b/lib/WebpackConfig.js @@ -40,6 +40,7 @@ class WebpackConfig { this.useVersioning = false; this.useSourceMaps = false; this.usePostCssLoader = false; + this.postCssLoaderOptionsCallback = function() {}; this.useSassLoader = false; this.sassLoaderOptionsCallback = function() {}; this.sassOptions = { @@ -198,8 +199,14 @@ class WebpackConfig { this.addEntry(name, files); } - enablePostCssLoader() { + enablePostCssLoader(postCssLoaderOptionsCallback = () => {}) { this.usePostCssLoader = true; + + if (typeof postCssLoaderOptionsCallback !== 'function') { + throw new Error('Argument 1 to enablePostCssLoader() must be a callback function.'); + } + + this.postCssLoaderOptionsCallback = postCssLoaderOptionsCallback; } enableSassLoader(sassLoaderOptionsCallback = () => {}, options = {}) { diff --git a/lib/loaders/css.js b/lib/loaders/css.js index 231f16d2..cc18ba98 100644 --- a/lib/loaders/css.js +++ b/lib/loaders/css.js @@ -38,11 +38,20 @@ module.exports = { if (usePostCssLoader) { loaderFeatures.ensureLoaderPackagesExist('postcss'); + const postCssLoaderOptions = { + sourceMap: webpackConfig.useSourceMaps + }; + + // allow options to be configured + webpackConfig.postCssLoaderOptionsCallback.apply( + // use config as the this variable + postCssLoaderOptions, + [postCssLoaderOptions] + ); + cssLoaders.push({ loader: 'postcss-loader', - options: { - sourceMap: webpackConfig.useSourceMaps - } + options: postCssLoaderOptions }); } diff --git a/test/WebpackConfig.js b/test/WebpackConfig.js index 06bdc71c..d65081ed 100644 --- a/test/WebpackConfig.js +++ b/test/WebpackConfig.js @@ -282,6 +282,30 @@ describe('WebpackConfig object', () => { }); }); + describe('enablePostCssLoader', () => { + it('Call with no config', () => { + const config = createConfig(); + config.enablePostCssLoader(); + + expect(config.usePostCssLoader).to.be.true; + }); + + it('Pass options callback', () => { + const config = createConfig(); + const callback = () => {}; + config.enablePostCssLoader(callback); + + expect(config.usePostCssLoader).to.be.true; + expect(config.postCssLoaderOptionsCallback).to.equal(callback); + }); + + it('Pass invalid options callback', () => { + const config = createConfig(); + + expect(() => config.enablePostCssLoader('FOO')).to.throw('must be a callback function'); + }); + }); + describe('enableSassLoader', () => { it('Call with no config', () => { const config = createConfig(); diff --git a/test/loaders/css.js b/test/loaders/css.js index 579b16b5..465c581d 100644 --- a/test/loaders/css.js +++ b/test/loaders/css.js @@ -44,14 +44,32 @@ describe('loaders/css', () => { expect(actualLoaders[0].options.minimize).to.be.true; }); - it('getLoaders() with PostCSS', () => { - const config = createConfig(); - config.enableSourceMaps(); - config.enablePostCssLoader(); + describe('getLoaders() with PostCSS', () => { + it('without options callback', () => { + const config = createConfig(); + config.enableSourceMaps(); + config.enablePostCssLoader(); - const actualLoaders = cssLoader.getLoaders(config); - // css-loader & postcss-loader - expect(actualLoaders).to.have.lengthOf(2); - expect(actualLoaders[1].options.sourceMap).to.be.true; + const actualLoaders = cssLoader.getLoaders(config); + // css-loader & postcss-loader + expect(actualLoaders).to.have.lengthOf(2); + expect(actualLoaders[1].options.sourceMap).to.be.true; + }); + + it('with options callback', () => { + const config = createConfig(); + config.enableSourceMaps(); + config.enablePostCssLoader((options) => { + options.config = { + path: 'config/postcss.config.js' + }; + }); + + const actualLoaders = cssLoader.getLoaders(config); + // css-loader & postcss-loader + expect(actualLoaders).to.have.lengthOf(2); + expect(actualLoaders[1].options.sourceMap).to.be.true; + expect(actualLoaders[1].options.config.path).to.equal('config/postcss.config.js'); + }); }); });