Skip to content

Commit ce1df2d

Browse files
committed
feature #201 Added CoffeeScript loader support (harentius)
This PR was squashed before being merged into the master branch (closes #201). Discussion ---------- Added CoffeeScript loader support Commits ------- 24634c7 corrected test description 3ed4a79 Added CoffeeScript loader support
2 parents e9c1c1a + 24634c7 commit ce1df2d

File tree

13 files changed

+232
-0
lines changed

13 files changed

+232
-0
lines changed

fixtures/js/index.coffee

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fun = () ->
2+
document.getElementById("app").innerHTML = "<h1>Welcome to Your Coffee App</h1>"
3+
4+
fun()

index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,27 @@ const publicApi = {
635635
return this;
636636
},
637637

638+
/**
639+
* Call this if you plan on loading CoffeeScript files.
640+
*
641+
* Encore.enableCoffeeScriptLoader()
642+
*
643+
* Or, configure the coffee-loader options:
644+
*
645+
* Encore.enableCoffeeScriptLoader(function(coffeeScriptOptions) {
646+
* // http://coffeescript.org/#nodejs-usage
647+
* // coffeeScriptOptions.header = true;
648+
* });
649+
*
650+
* @param {function} callback
651+
* @return {exports}
652+
*/
653+
enableCoffeeScriptLoader(callback = () => {}) {
654+
webpackConfig.enableCoffeeScriptLoader(callback);
655+
656+
return this;
657+
},
658+
638659
/**
639660
* Call this to enable forked type checking for TypeScript loader
640661
* https://github.com/TypeStrong/ts-loader/blob/v2.3.0/README.md#faster-builds

lib/WebpackConfig.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class WebpackConfig {
6262
this.usePreact = false;
6363
this.useVueLoader = false;
6464
this.useTypeScriptLoader = false;
65+
this.useCoffeeScriptLoader = false;
6566
this.useForkedTypeScriptTypeChecking = false;
6667
this.useWebpackNotifier = false;
6768

@@ -81,6 +82,7 @@ class WebpackConfig {
8182
this.babelConfigurationCallback = () => {};
8283
this.vueLoaderOptionsCallback = () => {};
8384
this.tsConfigurationCallback = () => {};
85+
this.coffeeScriptConfigurationCallback = () => {};
8486

8587
// Plugins options
8688
this.cleanWebpackPluginPaths = ['**/*'];
@@ -411,6 +413,16 @@ class WebpackConfig {
411413
forkedTypeScriptTypesCheckOptionsCallback;
412414
}
413415

416+
enableCoffeeScriptLoader(callback = () => {}) {
417+
this.useCoffeeScriptLoader = true;
418+
419+
if (typeof callback !== 'function') {
420+
throw new Error('Argument 1 to enableCoffeeScriptLoader() must be a callback function.');
421+
}
422+
423+
this.coffeeScriptConfigurationCallback = callback;
424+
}
425+
414426
enableVueLoader(vueLoaderOptionsCallback = () => {}) {
415427
this.useVueLoader = true;
416428

lib/config-generator.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const lessLoaderUtil = require('./loaders/less');
1818
const stylusLoaderUtil = require('./loaders/stylus');
1919
const babelLoaderUtil = require('./loaders/babel');
2020
const tsLoaderUtil = require('./loaders/typescript');
21+
const coffeeScriptLoaderUtil = require('./loaders/coffee-script');
2122
const vueLoaderUtil = require('./loaders/vue');
2223
// plugins utils
2324
const extractTextPluginUtil = require('./plugins/extract-text');
@@ -211,6 +212,13 @@ class ConfigGenerator {
211212
});
212213
}
213214

215+
if (this.webpackConfig.useCoffeeScriptLoader) {
216+
rules.push({
217+
test: /\.coffee$/,
218+
use: coffeeScriptLoaderUtil.getLoaders(this.webpackConfig)
219+
});
220+
}
221+
214222
this.webpackConfig.loaders.forEach((loader) => {
215223
rules.push(loader);
216224
});

lib/features.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ const features = {
5151
packages: ['typescript', 'ts-loader'],
5252
description: 'process TypeScript files'
5353
},
54+
coffeescript: {
55+
method: 'enableCoffeeScriptLoader()',
56+
packages: ['coffeescript', 'coffee-loader'],
57+
description: 'process CoffeeScript files'
58+
},
5459
forkedtypecheck: {
5560
method: 'enableForkedTypeScriptTypesChecking()',
5661
packages: ['typescript', 'ts-loader', 'fork-ts-checker-webpack-plugin'],

lib/loaders/coffee-script.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* This file is part of the Symfony Webpack Encore package.
3+
*
4+
* (c) Fabien Potencier <[email protected]>
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+
14+
/**
15+
* @param {WebpackConfig} webpackConfig
16+
* @return {Array} of loaders to use for coffeescript files
17+
*/
18+
module.exports = {
19+
getLoaders(webpackConfig) {
20+
loaderFeatures.ensurePackagesExist('coffeescript');
21+
22+
const options = {
23+
sourceMap: webpackConfig.useSourceMaps,
24+
transpile: {
25+
presets: ['env']
26+
}
27+
};
28+
29+
// allow options to be configured
30+
webpackConfig.coffeeScriptConfigurationCallback.apply(
31+
options,
32+
[options]
33+
);
34+
35+
return [
36+
{
37+
loader: 'coffee-loader',
38+
options: options,
39+
},
40+
];
41+
}
42+
};

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
"babel-preset-react": "^6.23.0",
5656
"chai": "^3.5.0",
5757
"chai-fs": "^1.0.0",
58+
"coffee-loader": "^0.9.0",
59+
"coffeescript": "^2.0.2",
5860
"eslint": "^3.19.0",
5961
"eslint-plugin-header": "^1.0.0",
6062
"eslint-plugin-node": "^4.2.2",

test/WebpackConfig.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,31 @@ describe('WebpackConfig object', () => {
608608
});
609609
});
610610

611+
describe('enableCoffeeScriptLoader', () => {
612+
it('Calling method sets it', () => {
613+
const config = createConfig();
614+
config.enableCoffeeScriptLoader();
615+
616+
expect(config.useCoffeeScriptLoader).to.be.true;
617+
});
618+
619+
it('Calling with callback', () => {
620+
const config = createConfig();
621+
const callback = () => {};
622+
config.enableCoffeeScriptLoader(callback);
623+
624+
expect(config.coffeeScriptConfigurationCallback).to.equal(callback);
625+
});
626+
627+
it('Calling with non-callback throws an error', () => {
628+
const config = createConfig();
629+
630+
expect(() => {
631+
config.enableCoffeeScriptLoader('FOO');
632+
}).to.throw('must be a callback function');
633+
});
634+
});
635+
611636
describe('enableVueLoader', () => {
612637
it('Call with no config', () => {
613638
const config = createConfig();

test/config-generator.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,30 @@ describe('The config-generator function', () => {
333333
});
334334
});
335335

336+
describe('enableCoffeeScriptLoader() adds the coffee-loader', () => {
337+
it('without enableCoffeeScriptLoader()', () => {
338+
const config = createConfig();
339+
config.outputPath = '/tmp/output/public-path';
340+
config.publicPath = '/public-path';
341+
config.addEntry('main', './main');
342+
const actualConfig = configGenerator(config);
343+
344+
expect(JSON.stringify(actualConfig.module.rules)).to.not.contain('coffee-loader');
345+
});
346+
347+
it('enableCoffeeScriptLoader()', () => {
348+
const config = createConfig();
349+
config.outputPath = '/tmp/output/public-path';
350+
config.publicPath = '/public-path';
351+
config.addEntry('main', './main');
352+
config.enableCoffeeScriptLoader();
353+
354+
const actualConfig = configGenerator(config);
355+
356+
expect(JSON.stringify(actualConfig.module.rules)).to.contain('coffee-loader');
357+
});
358+
});
359+
336360
describe('addLoader() adds a custom loader', () => {
337361
it('addLoader()', () => {
338362
const config = createConfig();

test/functional.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,37 @@ module.exports = {
831831
}).to.throw('wrong `tsconfig` path in fork plugin configuration (should be a relative or absolute path)');
832832
});
833833

834+
it('When configured, CoffeeScript is compiled', (done) => {
835+
const config = createWebpackConfig('www/build', 'dev');
836+
config.setPublicPath('/build');
837+
config.addEntry('main', ['./js/index.coffee']);
838+
const testCallback = () => {};
839+
config.enableCoffeeScriptLoader(testCallback);
840+
841+
testSetup.runWebpack(config, (webpackAssert) => {
842+
webpackAssert.assertOutputFileContains(
843+
'main.js',
844+
'return document.getElementById("app").innerHTML = "<h1>Welcome to Your Coffee App</h1>"'
845+
);
846+
847+
expect(config.outputPath).to.be.a.directory().with.deep.files([
848+
'main.js',
849+
'manifest.json'
850+
]);
851+
852+
testSetup.requestTestPage(
853+
path.join(config.getContext(), 'www'),
854+
[
855+
'build/main.js'
856+
],
857+
(browser) => {
858+
browser.assert.text('#app h1', 'Welcome to Your Coffee App');
859+
done();
860+
}
861+
);
862+
});
863+
});
864+
834865
it('The output directory is cleaned between builds', (done) => {
835866
const config = createWebpackConfig('www/build', 'dev');
836867
config.setPublicPath('/build');

test/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,15 @@ describe('Public API', () => {
224224

225225
});
226226

227+
describe('enableCoffeeScriptLoader', () => {
228+
229+
it('must return the API object', () => {
230+
const returnedValue = api.enableCoffeeScriptLoader();
231+
expect(returnedValue).to.equal(api);
232+
});
233+
234+
});
235+
227236
describe('enableForkedTypeScriptTypesChecking', () => {
228237

229238
it('must return the API object', () => {

test/loaders/coffee-script.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* This file is part of the Symfony Webpack Encore package.
3+
*
4+
* (c) Fabien Potencier <[email protected]>
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 expect = require('chai').expect;
13+
const WebpackConfig = require('../../lib/WebpackConfig');
14+
const RuntimeConfig = require('../../lib/config/RuntimeConfig');
15+
const coffeeScriptLoader = require('../../lib/loaders/coffee-script');
16+
17+
function createConfig() {
18+
const runtimeConfig = new RuntimeConfig();
19+
runtimeConfig.context = __dirname;
20+
runtimeConfig.babelRcFileExists = false;
21+
22+
return new WebpackConfig(runtimeConfig);
23+
}
24+
25+
describe('loaders/coffee-script', () => {
26+
it('getLoaders() with callback', () => {
27+
const config = createConfig();
28+
config.enableSourceMaps(true);
29+
config.enableCoffeeScriptLoader(function(options) {
30+
options.header = true;
31+
});
32+
33+
const loaders = coffeeScriptLoader.getLoaders(config);
34+
expect(loaders[0].options).to.deep.include({
35+
sourceMap: true,
36+
header: true,
37+
});
38+
});
39+
});

yarn.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,16 @@ code-point-at@^1.0.0:
14111411
version "1.1.0"
14121412
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
14131413

1414+
coffee-loader@^0.9.0:
1415+
version "0.9.0"
1416+
resolved "https://registry.yarnpkg.com/coffee-loader/-/coffee-loader-0.9.0.tgz#6deabd336062ddc6d773da4dfd16367fc7107bd6"
1417+
dependencies:
1418+
loader-utils "^1.0.2"
1419+
1420+
coffeescript@^2.0.2:
1421+
version "2.0.2"
1422+
resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.0.2.tgz#065702a484b46194b8c7eb08481e6d4dc38b87c9"
1423+
14141424
collection-visit@^1.0.0:
14151425
version "1.0.0"
14161426
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"

0 commit comments

Comments
 (0)