diff --git a/lib/WebpackConfig.js b/lib/WebpackConfig.js index f51b27dc..82c003e0 100644 --- a/lib/WebpackConfig.js +++ b/lib/WebpackConfig.js @@ -102,18 +102,15 @@ class WebpackConfig { this.handlebarsConfigurationCallback = () => {}; this.loaderConfigurationCallbacks = { javascript: () => {}, - js: () => {}, css: () => {}, images: () => {}, fonts: () => {}, sass: () => {}, - scss: () => {}, less: () => {}, stylus: () => {}, vue: () => {}, eslint: () => {}, typescript: () => {}, - ts: () => {}, handlebars: () => {}, }; @@ -735,8 +732,19 @@ class WebpackConfig { configureLoaderRule(name, callback) { logger.warning('Be careful when using Encore.configureLoaderRule(), this is a low-level method that can potentially breaks Encore and Webpack when not used carefully.'); + // Key: alias, Value: existing loader in `this.loaderConfigurationCallbacks` + const aliases = { + js: 'javascript', + ts: 'typescript', + scss: 'sass', + }; + + if (name in aliases) { + name = aliases[name]; + } + if (!(name in this.loaderConfigurationCallbacks)) { - throw new Error(`Loader "${name}" is not configurable. Valid loaders are "${Object.keys(this.loaderConfigurationCallbacks).join('", "')}".`); + throw new Error(`Loader "${name}" is not configurable. Valid loaders are "${Object.keys(this.loaderConfigurationCallbacks).join('", "')}" and the aliases "${Object.keys(aliases).join('", "')}".`); } if (typeof callback !== 'function') { diff --git a/lib/config-generator.js b/lib/config-generator.js index 00ab6688..29555454 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -222,25 +222,11 @@ class ConfigGenerator { buildRulesConfig() { const applyRuleConfigurationCallback = (name, defaultRules) => { - if (!(name in this.webpackConfig.loaderConfigurationCallbacks)) { - throw new Error(`Loader "${name}" is not configurable. Valid loaders are "${Object.keys(this.webpackConfig.loaderConfigurationCallbacks).join('", "')}".`); - } - return applyOptionsCallback(this.webpackConfig.loaderConfigurationCallbacks[name], defaultRules); }; - const applyRuleConfigurationCallbacks = (names, defaultRules) => { - let rules = defaultRules; - - names.forEach(name => { - rules = applyRuleConfigurationCallback(name, rules); - }); - - return rules; - }; - let rules = [ - applyRuleConfigurationCallbacks(['javascript', 'js'], { + applyRuleConfigurationCallback('javascript', { // match .js and .jsx test: /\.jsx?$/, exclude: this.webpackConfig.babelOptions.exclude, @@ -323,7 +309,7 @@ class ConfigGenerator { } if (this.webpackConfig.useSassLoader) { - rules.push(applyRuleConfigurationCallbacks(['sass', 'scss'], { + rules.push(applyRuleConfigurationCallback('sass', { test: /\.s[ac]ss$/, oneOf: [ { @@ -385,7 +371,7 @@ class ConfigGenerator { } if (this.webpackConfig.useTypeScriptLoader) { - rules.push(applyRuleConfigurationCallbacks(['typescript', 'ts'], { + rules.push(applyRuleConfigurationCallback('typescript', { test: /\.tsx?$/, exclude: /node_modules/, use: tsLoaderUtil.getLoaders(this.webpackConfig) diff --git a/test/WebpackConfig.js b/test/WebpackConfig.js index 3cfa9d4c..17eb8f89 100644 --- a/test/WebpackConfig.js +++ b/test/WebpackConfig.js @@ -1161,7 +1161,7 @@ describe('WebpackConfig object', () => { expect(() => { config.configureLoaderRule('reason'); - }).to.throw('Loader "reason" is not configurable. Valid loaders are "javascript", "js", "css", "images", "fonts", "sass", "scss", "less", "stylus", "vue", "eslint", "typescript", "ts", "handlebars".'); + }).to.throw('Loader "reason" is not configurable. Valid loaders are "javascript", "css", "images", "fonts", "sass", "less", "stylus", "vue", "eslint", "typescript", "handlebars" and the aliases "js", "ts", "scss".'); }); it('Call method with not a valid callback', () => { diff --git a/test/config-generator.js b/test/config-generator.js index 73a3cb50..64bc7e4e 100644 --- a/test/config-generator.js +++ b/test/config-generator.js @@ -1025,11 +1025,23 @@ describe('The config-generator function', () => { config.enableSingleRuntimeChunk(); }); - it('configure rule for "javascript and "js"', () => { + it('configure rule for "javascript"', () => { config.configureLoaderRule('javascript', (loaderRule) => { loaderRule.test = /\.m?js$/; + loaderRule.use[0].options.fooBar = 'fooBar'; }); + + const webpackConfig = configGenerator(config); + const rule = findRule(/\.m?js$/, webpackConfig.module.rules); + + expect('file.js').to.match(rule.test); + expect('file.mjs').to.match(rule.test); + expect(rule.use[0].options.fooBar).to.equal('fooBar'); + }); + + it('configure rule for the alias "js"', () => { config.configureLoaderRule('js', (loaderRule) => { + loaderRule.test = /\.m?js$/; loaderRule.use[0].options.fooBar = 'fooBar'; }); @@ -1074,20 +1086,28 @@ describe('The config-generator function', () => { expect(rule.options.name).to.equal('dirname-fonts/[hash:42].[ext]'); }); - it('configure rule for "sass" and "scss"', () => { + it('configure rule for "sass"', () => { config.enableSassLoader(); config.configureLoaderRule('sass', (loaderRule) => { - loaderRule.use.push('Option pushed when configuring Sass.'); + loaderRule.use[2].options.fooBar = 'fooBar'; }); + + const webpackConfig = configGenerator(config); + const rule = findRule(/\.s[ac]ss$/, webpackConfig.module.rules); + + expect(rule.use[2].options.fooBar).to.equal('fooBar'); + }); + + it('configure rule for the alias "scss"', () => { + config.enableSassLoader(); config.configureLoaderRule('scss', (loaderRule) => { - loaderRule.use.push('Option pushed when configuring SCSS.'); + loaderRule.use[2].options.fooBar = 'fooBar'; }); const webpackConfig = configGenerator(config); const rule = findRule(/\.s[ac]ss$/, webpackConfig.module.rules); - expect(rule.use.pop()).to.equal('Option pushed when configuring SCSS.'); - expect(rule.use.pop()).to.equal('Option pushed when configuring Sass.'); + expect(rule.use[2].options.fooBar).to.equal('fooBar'); }); it('configure rule for "less"', () => { @@ -1159,8 +1179,20 @@ describe('The config-generator function', () => { config.configureLoaderRule('typescript', (loaderRule) => { loaderRule.use[1].options.happyPackMode = true; }); + + const webpackConfig = configGenerator(config); + const rule = findRule(/\.tsx?$/, webpackConfig.module.rules); + + expect(rule.use[1].options.silent).to.be.true; + expect(rule.use[1].options.happyPackMode).to.be.true; + }); + + it('configure rule for the alias "ts"', () => { + config.enableTypeScriptLoader((options) => { + options.silent = true; + }); config.configureLoaderRule('ts', (loaderRule) => { - loaderRule.use[1].options.logInfoToStdOut = true; + loaderRule.use[1].options.happyPackMode = true; }); const webpackConfig = configGenerator(config); @@ -1168,7 +1200,6 @@ describe('The config-generator function', () => { expect(rule.use[1].options.silent).to.be.true; expect(rule.use[1].options.happyPackMode).to.be.true; - expect(rule.use[1].options.logInfoToStdOut).to.be.true; }); it('configure rule for "handlebars"', () => {