diff --git a/index.js b/index.js index ca02b927..63432664 100644 --- a/index.js +++ b/index.js @@ -330,10 +330,21 @@ module.exports = { /** * Call this if you plan on loading less files. * + * Encore.enableLessLoader(); + * + * Or pass options to the loader + * + * Encore.enableLessLoader(function(options) { + * // https://github.com/webpack-contrib/less-loader#examples + * // http://lesscss.org/usage/#command-line-usage-options + * // options.relativeUrls = false; + * }); + * + * @param {function} lessLoaderOptionsCallback * @return {exports} */ - enableLessLoader() { - webpackConfig.enableLessLoader(); + enableLessLoader(lessLoaderOptionsCallback = () => {}) { + webpackConfig.enableLessLoader(lessLoaderOptionsCallback); return this; }, diff --git a/lib/WebpackConfig.js b/lib/WebpackConfig.js index 81dbf669..706ec597 100644 --- a/lib/WebpackConfig.js +++ b/lib/WebpackConfig.js @@ -47,6 +47,7 @@ class WebpackConfig { resolve_url_loader: true }; this.useLessLoader = false; + this.lessLoaderOptionsCallback = function() {}; this.cleanupOutput = false; this.sharedCommonsEntryName = null; this.providedVariables = {}; @@ -231,8 +232,14 @@ class WebpackConfig { } } - enableLessLoader() { + enableLessLoader(lessLoaderOptionsCallback = () => {}) { this.useLessLoader = true; + + if (typeof lessLoaderOptionsCallback !== 'function') { + throw new Error('Argument 1 to enableLessLoader() must be a callback function.'); + } + + this.lessLoaderOptionsCallback = lessLoaderOptionsCallback; } enableReactPreset() { diff --git a/lib/loaders/less.js b/lib/loaders/less.js index 1324f1a7..e3986a7a 100644 --- a/lib/loaders/less.js +++ b/lib/loaders/less.js @@ -21,13 +21,22 @@ module.exports = { getLoaders(webpackConfig, ignorePostCssLoader = false) { loaderFeatures.ensureLoaderPackagesExist('less'); + const config = { + sourceMap: webpackConfig.useSourceMaps + }; + + // allow options to be configured + webpackConfig.lessLoaderOptionsCallback.apply( + // use config as the this variable + config, + [config] + ); + return [ ...cssLoader.getLoaders(webpackConfig, ignorePostCssLoader), { loader: 'less-loader', - options: { - sourceMap: webpackConfig.useSourceMaps - } + options: config }, ]; } diff --git a/test/WebpackConfig.js b/test/WebpackConfig.js index 016d0636..8cfdccea 100644 --- a/test/WebpackConfig.js +++ b/test/WebpackConfig.js @@ -339,6 +339,31 @@ describe('WebpackConfig object', () => { }); }); + describe('enableLessLoader', () => { + it('Calling method sets it', () => { + const config = createConfig(); + config.enableLessLoader(); + + expect(config.useLessLoader).to.be.true; + }); + + it('Calling with callback', () => { + const config = createConfig(); + const callback = (lessOptions) => {}; + config.enableLessLoader(callback); + + expect(config.lessLoaderOptionsCallback).to.equal(callback); + }); + + it('Calling with non-callback throws an error', () => { + const config = createConfig(); + + expect(() => { + config.enableLessLoader('FOO'); + }).to.throw('must be a callback function'); + }); + }); + describe('enableTypeScriptLoader', () => { it('Calling method sets it', () => { const config = createConfig(); diff --git a/test/loaders/less.js b/test/loaders/less.js index 403da23c..ec7826fc 100644 --- a/test/loaders/less.js +++ b/test/loaders/less.js @@ -39,4 +39,26 @@ describe('loaders/less', () => { cssLoader.getLoaders.restore(); }); + + it('getLoaders() with options callback', () => { + const config = createConfig(); + config.enableSourceMaps(true); + + // make the cssLoader return nothing + sinon.stub(cssLoader, 'getLoaders') + .callsFake(() => []); + + config.enableLessLoader(function(lessOptions) { + lessOptions.custom_option = 'foo'; + lessOptions.other_option = true; + }); + + const actualLoaders = lessLoader.getLoaders(config); + expect(actualLoaders[0].options).to.deep.equals({ + sourceMap: true, + custom_option: 'foo', + other_option: true + }); + cssLoader.getLoaders.restore(); + }); });