Skip to content

Commit 5cf3d02

Browse files
committed
feat: add missing loaders, add more tests
1 parent 86dc788 commit 5cf3d02

File tree

5 files changed

+204
-43
lines changed

5 files changed

+204
-43
lines changed

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,8 +1112,8 @@ class Encore {
11121112
* Encore
11131113
* .enableEslintLoader()
11141114
* .enableVueLoader()
1115-
* .configureLoaderRule('eslint', (loader) => {
1116-
* loader.test = /\.(jsx?|vue)/;
1115+
* .configureLoaderRule('eslint', (loaderRule) => {
1116+
* loaderRule.test = /\.(jsx?|vue)/;
11171117
* });
11181118
*
11191119
* @param {string} name

lib/WebpackConfig.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,20 @@ class WebpackConfig {
101101
this.tsConfigurationCallback = () => {};
102102
this.handlebarsConfigurationCallback = () => {};
103103
this.loaderConfigurationCallbacks = {
104-
'eslint': () => {},
104+
javascript: () => {},
105+
js: () => {},
106+
css: () => {},
107+
images: () => {},
108+
fonts: () => {},
109+
sass: () => {},
110+
scss: () => {},
111+
less: () => {},
112+
stylus: () => {},
113+
vue: () => {},
114+
eslint: () => {},
115+
typescript: () => {},
116+
ts: () => {},
117+
handlebars: () => {},
105118
};
106119

107120
// Plugins options

lib/config-generator.js

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,24 @@ class ConfigGenerator {
229229
return applyOptionsCallback(this.webpackConfig.loaderConfigurationCallbacks[name], defaultRules);
230230
};
231231

232+
const applyRuleConfigurationCallbacks = (names, defaultRules) => {
233+
let rules = defaultRules;
234+
235+
names.forEach(name => {
236+
rules = applyRuleConfigurationCallback(name, rules);
237+
});
238+
239+
return rules;
240+
};
241+
232242
let rules = [
233-
{
243+
applyRuleConfigurationCallbacks(['javascript', 'js'], {
234244
// match .js and .jsx
235245
test: /\.jsx?$/,
236246
exclude: this.webpackConfig.babelOptions.exclude,
237247
use: babelLoaderUtil.getLoaders(this.webpackConfig)
238-
},
239-
{
248+
}),
249+
applyRuleConfigurationCallback('css', {
240250
test: /\.css$/,
241251
oneOf: [
242252
{
@@ -253,7 +263,7 @@ class ConfigGenerator {
253263
)
254264
}
255265
]
256-
}
266+
})
257267
];
258268

259269
if (this.webpackConfig.useImagesLoader) {
@@ -277,11 +287,11 @@ class ConfigGenerator {
277287
Object.assign(loaderOptions, this.webpackConfig.urlLoaderOptions.images);
278288
}
279289

280-
rules.push({
290+
rules.push(applyRuleConfigurationCallback('images', {
281291
test: /\.(png|jpg|jpeg|gif|ico|svg|webp)$/,
282292
loader: loaderName,
283293
options: loaderOptions
284-
});
294+
}));
285295
}
286296

287297
if (this.webpackConfig.useFontsLoader) {
@@ -305,15 +315,15 @@ class ConfigGenerator {
305315
Object.assign(loaderOptions, this.webpackConfig.urlLoaderOptions.fonts);
306316
}
307317

308-
rules.push({
318+
rules.push(applyRuleConfigurationCallback('fonts', {
309319
test: /\.(woff|woff2|ttf|eot|otf)$/,
310320
loader: loaderName,
311321
options: loaderOptions
312-
});
322+
}));
313323
}
314324

315325
if (this.webpackConfig.useSassLoader) {
316-
rules.push({
326+
rules.push(applyRuleConfigurationCallbacks(['sass', 'scss'], {
317327
test: /\.s[ac]ss$/,
318328
oneOf: [
319329
{
@@ -324,11 +334,11 @@ class ConfigGenerator {
324334
use: cssExtractLoaderUtil.prependLoaders(this.webpackConfig, sassLoaderUtil.getLoaders(this.webpackConfig))
325335
}
326336
]
327-
});
337+
}));
328338
}
329339

330340
if (this.webpackConfig.useLessLoader) {
331-
rules.push({
341+
rules.push(applyRuleConfigurationCallback('less', {
332342
test: /\.less/,
333343
oneOf: [
334344
{
@@ -339,11 +349,11 @@ class ConfigGenerator {
339349
use: cssExtractLoaderUtil.prependLoaders(this.webpackConfig, lessLoaderUtil.getLoaders(this.webpackConfig))
340350
}
341351
]
342-
});
352+
}));
343353
}
344354

345355
if (this.webpackConfig.useStylusLoader) {
346-
rules.push({
356+
rules.push(applyRuleConfigurationCallback('stylus', {
347357
test: /\.styl/,
348358
oneOf: [
349359
{
@@ -354,14 +364,14 @@ class ConfigGenerator {
354364
use: cssExtractLoaderUtil.prependLoaders(this.webpackConfig, stylusLoaderUtil.getLoaders(this.webpackConfig))
355365
}
356366
]
357-
});
367+
}));
358368
}
359369

360370
if (this.webpackConfig.useVueLoader) {
361-
rules.push({
371+
rules.push(applyRuleConfigurationCallback('vue', {
362372
test: /\.vue$/,
363373
use: vueLoaderUtil.getLoaders(this.webpackConfig)
364-
});
374+
}));
365375
}
366376

367377
if (this.webpackConfig.useEslintLoader) {
@@ -375,18 +385,18 @@ class ConfigGenerator {
375385
}
376386

377387
if (this.webpackConfig.useTypeScriptLoader) {
378-
rules.push({
388+
rules.push(applyRuleConfigurationCallbacks(['typescript', 'ts'], {
379389
test: /\.tsx?$/,
380390
exclude: /node_modules/,
381391
use: tsLoaderUtil.getLoaders(this.webpackConfig)
382-
});
392+
}));
383393
}
384394

385395
if (this.webpackConfig.useHandlebarsLoader) {
386-
rules.push({
396+
rules.push(applyRuleConfigurationCallback('handlebars', {
387397
test: /\.(handlebars|hbs)$/,
388398
use: handlebarsLoaderUtil.getLoaders(this.webpackConfig)
389-
});
399+
}));
390400
}
391401

392402
this.webpackConfig.loaders.forEach((loader) => {

test/WebpackConfig.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,8 +1160,8 @@ describe('WebpackConfig object', () => {
11601160
const config = createConfig();
11611161

11621162
expect(() => {
1163-
config.configureLoaderRule('vue');
1164-
}).to.throw('Loader "vue" is not configurable. Valid loaders are "eslint".');
1163+
config.configureLoaderRule('reason');
1164+
}).to.throw('Loader "reason" is not configurable. Valid loaders are "javascript", "js", "css", "images", "fonts", "sass", "scss", "less", "stylus", "vue", "eslint", "typescript", "ts", "handlebars".');
11651165
});
11661166

11671167
it('Call method with not a valid callback', () => {

test/config-generator.js

Lines changed: 156 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,34 +1018,172 @@ describe('The config-generator function', () => {
10181018
describe('Test configureLoaderRule()', () => {
10191019
let config;
10201020

1021-
const getLoader = (loaderName) => {
1022-
const webpackConfig = configGenerator(config);
1023-
return webpackConfig.module.rules.find(rule => rule.loader === loaderName);
1024-
};
1025-
10261021
beforeEach(() => {
10271022
config = createConfig();
10281023
config.outputPath = '/tmp/public/build';
10291024
config.setPublicPath('/');
1025+
config.enableSingleRuntimeChunk();
1026+
});
1027+
1028+
it('configure rule for "javascript and "js"', () => {
1029+
config.configureLoaderRule('javascript', (loaderRule) => {
1030+
loaderRule.test = /\.m?js$/;
1031+
});
1032+
config.configureLoaderRule('js', (loaderRule) => {
1033+
loaderRule.use[0].options.fooBar = 'fooBar';
1034+
});
1035+
1036+
const webpackConfig = configGenerator(config);
1037+
const rule = findRule(/\.m?js$/, webpackConfig.module.rules);
1038+
1039+
expect('file.js').to.match(rule.test);
1040+
expect('file.mjs').to.match(rule.test);
1041+
expect(rule.use[0].options.fooBar).to.equal('fooBar');
1042+
});
1043+
1044+
it('configure rule for "css"', () => {
1045+
config.configureLoaderRule('css', (loaderRule) => {
1046+
loaderRule.camelCase = true;
1047+
});
1048+
1049+
const webpackConfig = configGenerator(config);
1050+
const rule = findRule(/\.css$/, webpackConfig.module.rules);
1051+
1052+
expect(rule.camelCase).to.be.true;
1053+
});
1054+
1055+
it('configure rule for "images"', () => {
1056+
config.configureLoaderRule('images', (loaderRule) => {
1057+
loaderRule.options.name = 'dirname-images/[hash:42].[ext]';
1058+
});
1059+
1060+
const webpackConfig = configGenerator(config);
1061+
const rule = findRule(/\.(png|jpg|jpeg|gif|ico|svg|webp)$/, webpackConfig.module.rules);
1062+
1063+
expect(rule.options.name).to.equal('dirname-images/[hash:42].[ext]');
1064+
});
1065+
1066+
it('configure rule for "fonts"', () => {
1067+
config.configureLoaderRule('fonts', (loader) => {
1068+
loader.options.name = 'dirname-fonts/[hash:42].[ext]';
1069+
});
1070+
1071+
const webpackConfig = configGenerator(config);
1072+
const rule = findRule(/\.(woff|woff2|ttf|eot|otf)$/, webpackConfig.module.rules);
1073+
1074+
expect(rule.options.name).to.equal('dirname-fonts/[hash:42].[ext]');
1075+
});
1076+
1077+
it('configure rule for "sass" and "scss"', () => {
1078+
config.enableSassLoader();
1079+
config.configureLoaderRule('sass', (loaderRule) => {
1080+
loaderRule.use.push('Option pushed when configuring Sass.');
1081+
});
1082+
config.configureLoaderRule('scss', (loaderRule) => {
1083+
loaderRule.use.push('Option pushed when configuring SCSS.');
1084+
});
1085+
1086+
const webpackConfig = configGenerator(config);
1087+
const rule = findRule(/\.s[ac]ss$/, webpackConfig.module.rules);
1088+
1089+
expect(rule.use.pop()).to.equal('Option pushed when configuring SCSS.');
1090+
expect(rule.use.pop()).to.equal('Option pushed when configuring Sass.');
1091+
});
1092+
1093+
it('configure rule for "less"', () => {
1094+
config.enableLessLoader((options) => {
1095+
options.optionA = 'optionA';
1096+
});
1097+
config.configureLoaderRule('less', (loaderRule) => {
1098+
loaderRule.use[2].options.optionB = 'optionB';
1099+
});
1100+
1101+
const webpackConfig = configGenerator(config);
1102+
const rule = findRule(/\.less/, webpackConfig.module.rules);
1103+
1104+
expect(rule.use[2].options.optionA).to.equal('optionA');
1105+
expect(rule.use[2].options.optionB).to.equal('optionB');
1106+
});
1107+
1108+
it('configure rule for "stylus"', () => {
1109+
config.enableStylusLoader((options) => {
1110+
options.optionA = 'optionA';
1111+
});
1112+
config.configureLoaderRule('stylus', (loaderRule) => {
1113+
loaderRule.use[2].options.optionB = 'optionB';
1114+
});
1115+
1116+
const webpackConfig = configGenerator(config);
1117+
const rule = findRule(/\.styl/, webpackConfig.module.rules);
1118+
1119+
expect(rule.use[2].options.optionA).to.equal('optionA');
1120+
expect(rule.use[2].options.optionB).to.equal('optionB');
1121+
});
1122+
1123+
it('configure rule for "vue"', () => {
1124+
config.enableVueLoader((options) => {
1125+
options.shadowMode = true;
1126+
});
1127+
config.configureLoaderRule('vue', (loaderRule) => {
1128+
loaderRule.use[0].options.prettify = false;
1129+
});
1130+
1131+
const webpackConfig = configGenerator(config);
1132+
const rule = findRule(/\.vue$/, webpackConfig.module.rules);
1133+
1134+
expect(rule.use[0].options.shadowMode).to.be.true;
1135+
expect(rule.use[0].options.prettify).to.be.false;
10301136
});
10311137

10321138
it('configure rule for "eslint"', () => {
1033-
config.enableEslintLoader();
1034-
config.configureLoaderRule('eslint', (loader) => {
1035-
loader.test = /\.(jsx?|vue)/;
1139+
config.enableEslintLoader((options) => {
1140+
options.extends = 'airbnb';
1141+
});
1142+
config.configureLoaderRule('eslint', (loaderRule) => {
1143+
loaderRule.test = /\.(jsx?|vue)/;
10361144
});
10371145

1038-
expect(getLoader('eslint-loader')).to.deep.equals({
1039-
test: /\.(jsx?|vue)/,
1040-
enforce: 'pre',
1041-
exclude: /node_modules/,
1042-
loader: 'eslint-loader',
1043-
options: {
1044-
cache: true,
1045-
emitWarning: true,
1046-
parser: 'babel-eslint'
1047-
}
1146+
const webpackConfig = configGenerator(config);
1147+
const rule = findRule(/\.(jsx?|vue)/, webpackConfig.module.rules);
1148+
1149+
expect(rule.options.extends).to.equal('airbnb');
1150+
expect('file.js').to.match(rule.test);
1151+
expect('file.jsx').to.match(rule.test);
1152+
expect('file.vue').to.match(rule.test);
1153+
});
1154+
1155+
it('configure rule for "typescript" and "ts"', () => {
1156+
config.enableTypeScriptLoader((options) => {
1157+
options.silent = true;
1158+
});
1159+
config.configureLoaderRule('typescript', (loaderRule) => {
1160+
loaderRule.use[1].options.happyPackMode = true;
10481161
});
1162+
config.configureLoaderRule('ts', (loaderRule) => {
1163+
loaderRule.use[1].options.logInfoToStdOut = true;
1164+
});
1165+
1166+
const webpackConfig = configGenerator(config);
1167+
const rule = findRule(/\.tsx?$/, webpackConfig.module.rules);
1168+
1169+
expect(rule.use[1].options.silent).to.be.true;
1170+
expect(rule.use[1].options.happyPackMode).to.be.true;
1171+
expect(rule.use[1].options.logInfoToStdOut).to.be.true;
1172+
});
1173+
1174+
it('configure rule for "handlebars"', () => {
1175+
config.enableHandlebarsLoader((options) => {
1176+
options.debug = true;
1177+
});
1178+
config.configureLoaderRule('handlebars', (loaderRule) => {
1179+
loaderRule.use[0].options.fooBar = 'fooBar';
1180+
});
1181+
1182+
const webpackConfig = configGenerator(config);
1183+
const rule = findRule(/\.(handlebars|hbs)$/, webpackConfig.module.rules);
1184+
1185+
expect(rule.use[0].options.debug).to.be.true;
1186+
expect(rule.use[0].options.fooBar).to.be.equal('fooBar');
10491187
});
10501188
});
10511189
});

0 commit comments

Comments
 (0)