Skip to content

Commit 0efcd3e

Browse files
committed
minor #22 Refactoring loaders into re-usable modules (weaverryan)
This PR was squashed before being merged into the master branch (closes #22). Discussion ---------- Refactoring loaders into re-usable modules This is intended to be an internal cosmetic change. The purpose (other than organization) is to help enable the Vue.js loader... which needs to be able to re-use most of this configuration. Commits ------- 529cc36 Refactoring loaders into re-usable modules
2 parents 91ebd53 + 529cc36 commit 0efcd3e

File tree

12 files changed

+502
-190
lines changed

12 files changed

+502
-190
lines changed

lib/config-generator.js

Lines changed: 13 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin');
1414
const ManifestPlugin = require('./webpack/webpack-manifest-plugin');
1515
const DeleteUnusedEntriesJSPlugin = require('./webpack/delete-unused-entries-js-plugin');
1616
const AssetOutputDisplayPlugin = require('./friendly-errors/asset-output-display-plugin');
17-
const loaderFeatures = require('./loader-features');
1817
const CleanWebpackPlugin = require('clean-webpack-plugin');
1918
const WebpackChunkHash = require('webpack-chunk-hash');
2019
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
@@ -23,6 +22,10 @@ const missingLoaderFormatter = require('./friendly-errors/formatters/missing-loa
2322
const missingPostCssConfigTransformer = require('./friendly-errors/transformers/missing-postcss-config');
2423
const missingPostCssConfigFormatter = require('./friendly-errors/formatters/missing-postcss-config');
2524
const pathUtil = require('./config/path-util');
25+
const cssLoaderUtil = require('./loaders/css');
26+
const sassLoaderUtil = require('./loaders/sass');
27+
const lessLoaderUtil = require('./loaders/less');
28+
const babelLoaderUtil = require('./loaders/babel');
2629

2730
class ConfigGenerator {
2831
/**
@@ -99,76 +102,18 @@ class ConfigGenerator {
99102
}
100103

101104
buildRulesConfig() {
102-
const cssLoaders = [
105+
let rules = [
103106
{
104-
loader: 'css-loader' + this.getSourceMapOption() + (this.webpackConfig.isProduction() ? '?minimize=1' : ''),
107+
// match .js and .jsx
108+
test: /\.jsx?$/,
109+
exclude: /(node_modules|bower_components)/,
110+
use: babelLoaderUtil.getLoaders(this.webpackConfig)
105111
},
106-
];
107-
if (this.webpackConfig.usePostCssLoader) {
108-
loaderFeatures.ensureLoaderPackagesExist('postcss');
109-
110-
cssLoaders.push({
111-
loader: 'postcss-loader' + this.getSourceMapOption(),
112-
});
113-
}
114-
115-
let babelConfig = {
116-
// improves performance by caching babel compiles
117-
// we add this option ALWAYS
118-
// https://github.com/babel/babel-loader#options
119-
cacheDirectory: true
120-
};
121-
122-
// configure babel (unless the user is specifying .babelrc)
123-
// todo - add a sanity check for their babelrc contents
124-
if (!this.webpackConfig.doesBabelRcFileExist()) {
125-
Object.assign(babelConfig, {
126-
presets: [
127-
['env', {
128-
// modules don't need to be transformed - webpack will parse
129-
// the modules for us. This is a performance improvement
130-
// https://babeljs.io/docs/plugins/preset-env/#optionsmodules
131-
modules: false,
132-
targets: {
133-
browsers: '> 1%',
134-
uglify: true
135-
},
136-
useBuiltIns: true
137-
}]
138-
],
139-
});
140-
141-
if (this.webpackConfig.useReact) {
142-
loaderFeatures.ensureLoaderPackagesExist('react');
143-
144-
babelConfig.presets.push('react');
145-
}
146-
147-
// allow for babel config to be controlled
148-
this.webpackConfig.babelConfigurationCallback.apply(
149-
// use babelConfig as the this variable
150-
babelConfig,
151-
[babelConfig]
152-
);
153-
}
154-
155-
let rules = [];
156-
rules.push({
157-
// match .js and .jsx
158-
test: /\.jsx?$/,
159-
exclude: /(node_modules|bower_components)/,
160-
use: {
161-
loader: 'babel-loader',
162-
options: babelConfig
163-
}
164-
});
165-
166-
rules = rules.concat([
167112
{
168113
test: /\.css$/,
169114
use: ExtractTextPlugin.extract({
170115
fallback: 'style-loader' + this.getSourceMapOption(),
171-
use: cssLoaders
116+
use: cssLoaderUtil.getLoaders(this.webpackConfig)
172117
})
173118
},
174119
{
@@ -187,51 +132,24 @@ class ConfigGenerator {
187132
publicPath: this.webpackConfig.getRealPublicPath()
188133
}
189134
},
190-
]);
135+
];
191136

192137
if (this.webpackConfig.useSassLoader) {
193-
loaderFeatures.ensureLoaderPackagesExist('sass');
194-
195-
const sassLoaders = [...cssLoaders];
196-
if (true === this.webpackConfig.sassOptions.resolve_url_loader) {
197-
// responsible for resolving SASS url() paths
198-
// without this, all url() paths must be relative to the
199-
// entry file, not the file that contains the url()
200-
sassLoaders.push({
201-
loader: 'resolve-url-loader' + this.getSourceMapOption(),
202-
});
203-
}
204-
205-
sassLoaders.push({
206-
loader: 'sass-loader',
207-
options: {
208-
// needed by the resolve-url-loader
209-
sourceMap: (true === this.webpackConfig.sassOptions.resolve_url_loader) || this.webpackConfig.useSourceMaps
210-
}
211-
});
212-
213138
rules.push({
214139
test: /\.s[ac]ss$/,
215140
use: ExtractTextPlugin.extract({
216141
fallback: 'style-loader' + this.getSourceMapOption(),
217-
use: sassLoaders
142+
use: sassLoaderUtil.getLoaders(this.webpackConfig)
218143
})
219144
});
220145
}
221146

222147
if (this.webpackConfig.useLessLoader) {
223-
loaderFeatures.ensureLoaderPackagesExist('less');
224-
225148
rules.push({
226149
test: /\.less/,
227150
use: ExtractTextPlugin.extract({
228151
fallback: 'style-loader' + this.getSourceMapOption(),
229-
use: [
230-
...cssLoaders,
231-
{
232-
loader: 'less-loader' + this.getSourceMapOption()
233-
},
234-
]
152+
use: lessLoaderUtil.getLoaders(this.webpackConfig)
235153
})
236154
});
237155
}

lib/loaders/babel.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* This file is part of the Symfony 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('../loader-features');
13+
14+
/**
15+
* @param {WebpackConfig} webpackConfig
16+
* @return {Array} of loaders to use for Babel
17+
*/
18+
module.exports = {
19+
getLoaders(webpackConfig) {
20+
let babelConfig = {
21+
// improves performance by caching babel compiles
22+
// we add this option ALWAYS
23+
// https://github.com/babel/babel-loader#options
24+
cacheDirectory: true
25+
};
26+
27+
// configure babel (unless the user is specifying .babelrc)
28+
// todo - add a sanity check for their babelrc contents
29+
if (!webpackConfig.doesBabelRcFileExist()) {
30+
Object.assign(babelConfig, {
31+
presets: [
32+
['env', {
33+
// modules don't need to be transformed - webpack will parse
34+
// the modules for us. This is a performance improvement
35+
// https://babeljs.io/docs/plugins/preset-env/#optionsmodules
36+
modules: false,
37+
targets: {
38+
browsers: '> 1%',
39+
uglify: true
40+
},
41+
useBuiltIns: true
42+
}]
43+
],
44+
});
45+
46+
if (webpackConfig.useReact) {
47+
loaderFeatures.ensureLoaderPackagesExist('react');
48+
49+
babelConfig.presets.push('react');
50+
}
51+
52+
// allow for babel config to be controlled
53+
webpackConfig.babelConfigurationCallback.apply(
54+
// use babelConfig as the this variable
55+
babelConfig,
56+
[babelConfig]
57+
);
58+
}
59+
60+
return [
61+
{
62+
loader: 'babel-loader',
63+
options: babelConfig
64+
}
65+
];
66+
}
67+
};

lib/loaders/css.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* This file is part of the Symfony 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('../loader-features');
13+
14+
/**
15+
* @param {WebpackConfig} webpackConfig
16+
* @return {Array} of loaders to use for CSS files
17+
*/
18+
module.exports = {
19+
getLoaders(webpackConfig) {
20+
const cssLoaders = [
21+
{
22+
loader: 'css-loader',
23+
options: {
24+
minimize: webpackConfig.isProduction(),
25+
sourceMap: webpackConfig.useSourceMaps
26+
}
27+
},
28+
];
29+
30+
if (webpackConfig.usePostCssLoader) {
31+
loaderFeatures.ensureLoaderPackagesExist('postcss');
32+
33+
cssLoaders.push({
34+
loader: 'postcss-loader',
35+
options: {
36+
sourceMap: webpackConfig.useSourceMaps
37+
}
38+
});
39+
}
40+
41+
return cssLoaders;
42+
}
43+
};

lib/loaders/less.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* This file is part of the Symfony 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('../loader-features');
13+
const cssLoader = require('./css');
14+
15+
/**
16+
* @param {WebpackConfig} webpackConfig
17+
* @return {Array} of loaders to use for Less files
18+
*/
19+
module.exports = {
20+
getLoaders(webpackConfig) {
21+
loaderFeatures.ensureLoaderPackagesExist('less');
22+
23+
return [
24+
...cssLoader.getLoaders(webpackConfig),
25+
{
26+
loader: 'less-loader',
27+
options: {
28+
sourceMap: webpackConfig.useSourceMaps
29+
}
30+
},
31+
];
32+
}
33+
};

lib/loaders/sass.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* This file is part of the Symfony 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('../loader-features');
13+
const cssLoader = require('./css');
14+
15+
/**
16+
* @param {WebpackConfig} webpackConfig
17+
* @return {Array} of loaders to use for Sass files
18+
*/
19+
module.exports = {
20+
getLoaders(webpackConfig) {
21+
loaderFeatures.ensureLoaderPackagesExist('sass');
22+
23+
const sassLoaders = [...cssLoader.getLoaders(webpackConfig)];
24+
if (true === webpackConfig.sassOptions.resolve_url_loader) {
25+
// responsible for resolving SASS url() paths
26+
// without this, all url() paths must be relative to the
27+
// entry file, not the file that contains the url()
28+
sassLoaders.push({
29+
loader: 'resolve-url-loader',
30+
options: {
31+
sourceMap: webpackConfig.useSourceMaps
32+
}
33+
});
34+
}
35+
36+
sassLoaders.push({
37+
loader: 'sass-loader',
38+
options: {
39+
// needed by the resolve-url-loader
40+
sourceMap: (true === webpackConfig.sassOptions.resolve_url_loader) || webpackConfig.useSourceMaps
41+
}
42+
});
43+
44+
return sassLoaders;
45+
}
46+
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"nsp": "^2.6.3",
6363
"postcss-loader": "^1.3.3",
6464
"sass-loader": "^6.0.3",
65+
"sinon": "^2.3.4",
6566
"zombie": "^5.0.5"
6667
}
6768
}

0 commit comments

Comments
 (0)