Skip to content

Commit 92548f1

Browse files
committed
feature #301 Added support for the handlebars-loader (ogiammetta)
This PR was merged into the master branch. Discussion ---------- Added support for the handlebars-loader First PR on GitHub, any feedback is appreciated! :) Commits ------- 3aafa2e Added support for the handlebars-loader
2 parents 62b6aef + 3aafa2e commit 92548f1

File tree

14 files changed

+264
-5
lines changed

14 files changed

+264
-5
lines changed

fixtures/js/handlebars.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
var template = require('../templates/template.hbs');
2+
3+
document.getElementById('app').innerHTML = template({
4+
title: 'Welcome to Your Handlebars App'
5+
});

fixtures/templates/template.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>{{ title }}</h1>

index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,27 @@ class Encore {
719719
return this;
720720
}
721721

722+
/**
723+
* Call this if you plan on loading Handlebars files.
724+
*
725+
* Encore.enableHandlebarsLoader();
726+
*
727+
* Or pass options to the loader
728+
*
729+
* Encore.enableHandlebarsLoader(function(options) {
730+
* // https://github.com/pcardune/handlebars-loader
731+
* // options.debug = true;
732+
* });
733+
*
734+
* @param {function} callback
735+
* @returns {Encore}
736+
*/
737+
enableHandlebarsLoader(callback = () => {}) {
738+
webpackConfig.enableHandlebarsLoader(callback);
739+
740+
return this;
741+
}
742+
722743
/**
723744
* Call this if you wish to disable the default
724745
* images loader.

lib/WebpackConfig.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class WebpackConfig {
6565
this.useCoffeeScriptLoader = false;
6666
this.useForkedTypeScriptTypeChecking = false;
6767
this.useWebpackNotifier = false;
68+
this.useHandlebarsLoader = false;
6869

6970
// Features/Loaders options
7071
this.sassOptions = {
@@ -87,6 +88,7 @@ class WebpackConfig {
8788
this.vueLoaderOptionsCallback = () => {};
8889
this.tsConfigurationCallback = () => {};
8990
this.coffeeScriptConfigurationCallback = () => {};
91+
this.handlebarsConfigurationCallback = () => {};
9092

9193
// Plugins options
9294
this.cleanWebpackPluginPaths = ['**/*'];
@@ -446,6 +448,16 @@ class WebpackConfig {
446448
this.notifierPluginOptionsCallback = notifierPluginOptionsCallback;
447449
}
448450

451+
enableHandlebarsLoader(callback = () => {}) {
452+
this.useHandlebarsLoader = true;
453+
454+
if (typeof callback !== 'function') {
455+
throw new Error('Argument 1 to enableHandlebarsLoader() must be a callback function.');
456+
}
457+
458+
this.handlebarsConfigurationCallback = callback;
459+
}
460+
449461
disableImagesLoader() {
450462
this.useImagesLoader = false;
451463
}

lib/config-generator.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const babelLoaderUtil = require('./loaders/babel');
2121
const tsLoaderUtil = require('./loaders/typescript');
2222
const coffeeScriptLoaderUtil = require('./loaders/coffee-script');
2323
const vueLoaderUtil = require('./loaders/vue');
24+
const handlebarsLoaderUtil = require('./loaders/handlebars');
2425
// plugins utils
2526
const extractTextPluginUtil = require('./plugins/extract-text');
2627
const deleteUnusedEntriesPluginUtil = require('./plugins/delete-unused-entries');
@@ -242,6 +243,13 @@ class ConfigGenerator {
242243
});
243244
}
244245

246+
if (this.webpackConfig.useHandlebarsLoader) {
247+
rules.push({
248+
test: /\.(handlebars|hbs)$/,
249+
use: handlebarsLoaderUtil.getLoaders(this.webpackConfig)
250+
});
251+
}
252+
245253
this.webpackConfig.loaders.forEach((loader) => {
246254
rules.push(loader);
247255
});

lib/features.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ const features = {
7777
method: 'configureUrlLoader()',
7878
packages: ['url-loader'],
7979
description: 'use the url-loader'
80+
},
81+
handlebars: {
82+
method: 'enableHandlebarsLoader()',
83+
packages: ['handlebars', 'handlebars-loader'],
84+
description: 'load Handlebars files'
8085
}
8186
};
8287

lib/loaders/handlebars.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* This file is part of the Symfony Webpack Encore package.
3+
*
4+
* (c) Fabien Potencier <fabien@symfony.com>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
'use strict';
11+
12+
const loaderFeatures = require('../features');
13+
const applyOptionsCallback = require('../utils/apply-options-callback');
14+
15+
/**
16+
* @param {WebpackConfig} webpackConfig
17+
* @return {Array} of loaders to use for Handlebars
18+
*/
19+
module.exports = {
20+
getLoaders(webpackConfig) {
21+
loaderFeatures.ensurePackagesExist('handlebars');
22+
23+
const options = {};
24+
25+
return [
26+
{
27+
loader: 'handlebars-loader',
28+
options: applyOptionsCallback(webpackConfig.handlebarsConfigurationCallback, options)
29+
}
30+
];
31+
}
32+
};

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
"eslint-plugin-header": "^1.0.0",
6363
"eslint-plugin-node": "^4.2.2",
6464
"fork-ts-checker-webpack-plugin": "^0.2.7",
65+
"handlebars": "^4.0.11",
66+
"handlebars-loader": "^1.7.0",
6567
"http-server": "^0.9.0",
6668
"less": "^2.7.2",
6769
"less-loader": "^4.0.2",

test/WebpackConfig.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,28 @@ describe('WebpackConfig object', () => {
685685
});
686686
});
687687

688+
describe('enableHandlebarsLoader', () => {
689+
690+
it('Call with no config', () => {
691+
const config = createConfig();
692+
config.enableHandlebarsLoader();
693+
694+
expect(config.useHandlebarsLoader).to.be.true;
695+
});
696+
697+
it('Pass config', () => {
698+
const config = createConfig();
699+
const callback = (options) => {
700+
options.debug = true;
701+
};
702+
config.enableHandlebarsLoader(callback);
703+
704+
expect(config.useHandlebarsLoader).to.be.true;
705+
expect(config.handlebarsConfigurationCallback).to.equal(callback);
706+
});
707+
708+
});
709+
688710
describe('addPlugin', () => {
689711
it('extends the current registered plugins', () => {
690712
const config = createConfig();

test/config-generator.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,32 @@ describe('The config-generator function', () => {
354354
});
355355
});
356356

357+
describe('enableHandlebarsLoader() adds the handlebars-loader', () => {
358+
359+
it('without enableHandlebarsLoader()', () => {
360+
const config = createConfig();
361+
config.outputPath = '/tmp/output/public-path';
362+
config.publicPath = '/public-path';
363+
config.addEntry('main', './main');
364+
const actualConfig = configGenerator(config);
365+
366+
expect(JSON.stringify(actualConfig.module.rules)).to.not.contain('handlebars-loader');
367+
});
368+
369+
it('enableHandlebarsLoader()', () => {
370+
const config = createConfig();
371+
config.outputPath = '/tmp/output/public-path';
372+
config.publicPath = '/public-path';
373+
config.addEntry('main', './main');
374+
config.enableHandlebarsLoader();
375+
376+
const actualConfig = configGenerator(config);
377+
378+
expect(JSON.stringify(actualConfig.module.rules)).to.contain('handlebars-loader');
379+
});
380+
381+
});
382+
357383
describe('addLoader() adds a custom loader', () => {
358384
it('addLoader()', () => {
359385
const config = createConfig();

0 commit comments

Comments
 (0)