Skip to content

Commit 9c98c8a

Browse files
committed
Make it work with extract text webpack plugin again.
1 parent fcc5782 commit 9c98c8a

File tree

7 files changed

+173
-40
lines changed

7 files changed

+173
-40
lines changed

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,22 @@ Usage
4646

4747
Add the following configuration to `webpack.config.js`:
4848

49+
var styling = require('styling')
50+
4951
module.exports = {
5052
module: {
5153
loaders: [
5254
{
5355
test: /\.style\.js/,
54-
loader: 'style!css!styling!babel'
56+
loader: styling('style!css', babel')
5557
}
5658
]
5759
}
5860
}
5961

62+
Function `styling` take configures loader and accepts two arguments, one for
63+
*postloaders* and one for *preloaders*.
64+
6065
Now you can write styles with the full power of JavaScript, `Button.styling.js`:
6166

6267
import styling from 'styling'
@@ -85,12 +90,15 @@ Styling is compatible with [extract-text-webpack-plugin][] so you can have your
8590
styles extracted into a separate CSS bundle by Webpack. This is how you
8691
configure it to do so:
8792

93+
var styling = require('styling')
94+
var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')
95+
8896
module.exports = {
8997
module: {
9098
loaders: [
9199
{
92100
test: /\.style\.js/,
93-
loader: ExtractTextWebpackPlugin.extract('style', css!styling!babel')
101+
loader: styling(ExtractTextWebpackPlugin.extract('style', css'), 'babel')
94102
}
95103
]
96104
},

browser.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @copyright 2015, Andrey Popp
3+
*/
4+
5+
var Styling = require('./Styling');
6+
7+
function styling(spec) {
8+
return new Styling(spec);
9+
}
10+
11+
module.exports = styling;

index.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22
* @copyright 2015, Andrey Popp
33
*/
44

5-
var Styling = require('./Styling');
5+
var omitRequest = require.resolve('./omit');
6+
var loaderRequest = require.resolve('./loader');
67

7-
function styling(spec) {
8-
return new Styling(spec);
8+
module.exports = function styling(post, pre) {
9+
if (Array.isArray(post)) {
10+
post = post.join('!');
11+
}
12+
if (Array.isArray(pre)) {
13+
pre = pre.join('!');
14+
}
15+
return [omitRequest, post, loaderRequest, pre || ''].join('!');
916
}
10-
11-
module.exports = styling;

loader.js

Lines changed: 100 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,77 @@
22
* @copyright 2015, Andrey Popp
33
*/
44

5-
var path = require('path');
6-
var Module = require('module');
7-
var Styling = require('./Styling');
8-
var renderStyling = require('./renderStyling');
5+
var path = require('path');
6+
var Module = require('module');
7+
var Styling = require('./Styling');
8+
var renderStylingSheet = require('./renderStylingSheet');
99

1010
var NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
1111
var NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
1212
var LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
1313
var SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
1414
var LimitChunkCountPlugin = require('webpack/lib/optimize/LimitChunkCountPlugin');
1515

16+
var renderStylingSheetMod = require.resolve('./renderStylingSheet');
17+
18+
var extractTextWebpackPluginKey;
19+
try {
20+
extractTextWebpackPluginKey = path.dirname(require.resolve('extract-text-webpack-plugin'));
21+
} catch (error) {}
1622

1723
module.exports = function styling(content) {
1824
this.cacheable();
19-
return content;
25+
if (this[__dirname] === false) {
26+
return '';
27+
} else if (typeof this[extractTextWebpackPluginKey] === 'function') {
28+
var cb = this.async();
29+
var request = this.request.split('!').slice(this.loaderIndex + 1).join('!');
30+
produce(this, request, function(err, result) {
31+
if (err) {
32+
cb(err);
33+
} else {
34+
setCompiledStyling(this, result);
35+
cb(null, '');
36+
}
37+
}.bind(this));
38+
} else if (this[extractTextWebpackPluginKey] === false) {
39+
return getCompiledStyling(this);
40+
} else {
41+
return '';
42+
}
2043
};
2144

22-
module.exports.pitch = function stylingPitch(request, precedingRequest) {
45+
module.exports.pitch = function stylingPitch(request, precedingRequest, data) {
46+
this.cacheable();
2347
if (this[__dirname] === false) {
48+
// if we already inside the loader
49+
return;
50+
} else if (extractTextWebpackPluginKey in this) {
51+
// if extract-text-webpack-plugin is active we do all work in a loader phase
2452
return;
53+
} else {
54+
var cb = this.async();
55+
produce(this, request, cb);
2556
}
26-
var childFilename = "styling-output-filename";
27-
var outputOptions = {filename: childFilename};
28-
var childCompiler = this._compilation.createChildCompiler("styling-compiler", outputOptions);
57+
};
58+
59+
function produce(loader, request, cb) {
60+
var outputFilename = "styling-output-filename";
61+
var outputOptions = {filename: outputFilename};
62+
var childCompiler = loader._compilation.createChildCompiler("styling-compiler", outputOptions);
2963
childCompiler.apply(new NodeTemplatePlugin(outputOptions));
3064
childCompiler.apply(new LibraryTemplatePlugin(null, "commonjs2"));
3165
childCompiler.apply(new NodeTargetPlugin());
32-
childCompiler.apply(new SingleEntryPlugin(this.context, "!!" + request));
66+
childCompiler.apply(new SingleEntryPlugin(loader.context, "!!" + request));
3367
childCompiler.apply(new LimitChunkCountPlugin({ maxChunks: 1 }));
3468

3569
var subCache = "subcache " + __dirname + " " + request;
3670

3771
childCompiler.plugin("compilation", function(compilation) {
3872
if (compilation.cache) {
39-
if(!compilation.cache[subCache])
73+
if(!compilation.cache[subCache]) {
4074
compilation.cache[subCache] = {};
75+
}
4176
compilation.cache = compilation.cache[subCache];
4277
}
4378
});
@@ -47,12 +82,15 @@ module.exports.pitch = function stylingPitch(request, precedingRequest) {
4782
childCompiler.plugin("this-compilation", function(compilation) {
4883
compilation.plugin("normal-module-loader", function(loaderContext) {
4984
loaderContext[__dirname] = false;
85+
if (extractTextWebpackPluginKey in loader) {
86+
loaderContext[extractTextWebpackPluginKey] = loader[extractTextWebpackPluginKey];
87+
}
5088
});
5189
});
5290

5391
var source;
5492
childCompiler.plugin("after-compile", function(compilation, callback) {
55-
source = compilation.assets[childFilename] && compilation.assets[childFilename].source();
93+
source = compilation.assets[outputFilename] && compilation.assets[outputFilename].source();
5694

5795
// Remove all chunk assets
5896
compilation.chunks.forEach(function(chunk) {
@@ -64,11 +102,13 @@ module.exports.pitch = function stylingPitch(request, precedingRequest) {
64102
callback();
65103
});
66104

67-
var callback = this.async();
105+
function callback(error, result) {
106+
cb(error, result);
107+
}
68108

69-
childCompiler.runAsChild(function(err, entries, compilation) {
70-
if (err) {
71-
return callback(err);
109+
childCompiler.runAsChild(function(error, entries, compilation) {
110+
if (error) {
111+
return callback(error);
72112
}
73113
if (compilation.errors.length > 0) {
74114
return callback(compilation.errors[0]);
@@ -77,23 +117,14 @@ module.exports.pitch = function stylingPitch(request, precedingRequest) {
77117
return callback(new Error("Didn't get a result from child compiler"));
78118
}
79119
compilation.fileDependencies.forEach(function(dep) {
80-
this.addDependency(dep);
81-
}, this);
120+
loader.addDependency(dep);
121+
});
82122
compilation.contextDependencies.forEach(function(dep) {
83-
this.addContextDependency(dep);
84-
}, this);
123+
loader.addContextDependency(dep);
124+
});
85125
try {
86-
var exports = this.exec(source, request);
87-
var stylesheet = [];
88-
for (var key in exports) {
89-
if (exports.hasOwnProperty(key)) {
90-
var styling = exports[key];
91-
if (Styling.is(styling)) {
92-
stylesheet = stylesheet.concat(renderStyling(key, styling));
93-
}
94-
}
95-
}
96-
var text = stylesheet.join('\n\n');
126+
var exports = loader.exec(source, request);
127+
var text = renderStylingSheet(exports);
97128
} catch (e) {
98129
return callback(e);
99130
}
@@ -102,5 +133,41 @@ module.exports.pitch = function stylingPitch(request, precedingRequest) {
102133
} else {
103134
callback();
104135
}
105-
}.bind(this));
106-
};
136+
});
137+
}
138+
139+
function findInArray(array, func) {
140+
for (var i = 0; i < array.length; i++) {
141+
if (func(array[i])) {
142+
return i;
143+
}
144+
}
145+
return -1;
146+
}
147+
148+
function getRootCompilation(loader) {
149+
var compiler = loader._compiler;
150+
var compilation = loader._compilation;
151+
while (compiler.parentCompilation) {
152+
compilation = compiler.parentCompilation;
153+
compiler = compilation.compiler;
154+
}
155+
return compilation;
156+
}
157+
158+
function setCompiledStyling(loader, styling) {
159+
var compilation = getRootCompilation(loader);
160+
if (compilation.__stylingCache === undefined) {
161+
compilation.__stylingCache = {};
162+
}
163+
compilation.__stylingCache[loader.request] = styling;
164+
}
165+
166+
function getCompiledStyling(loader) {
167+
var compilation = getRootCompilation(loader);
168+
if (compilation.__stylingCache === undefined) {
169+
return undefined;
170+
} else {
171+
return compilation.__stylingCache[loader.request];
172+
}
173+
}

omit.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var loaderPath = require.resolve('./loader');
2+
3+
module.exports = function(content) {
4+
this.cacheable();
5+
return content;
6+
}
7+
8+
module.exports.pitch = function(request) {
9+
if (this[__dirname] === false) {
10+
request = request.split('!');
11+
while (request.length > 1) {
12+
var req = request.shift();
13+
if (req === loaderPath) {
14+
break;
15+
}
16+
}
17+
request = request.join('!');
18+
return 'module.exports = require(' + JSON.stringify('!!' + request) + ');';
19+
}
20+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"version": "0.2.0",
44
"description": "Style components with JavaScript",
55
"main": "index.js",
6+
"browser": "browser.js",
67
"webpackLoader": "loader.js",
78
"author": "Andrey Popp <[email protected]>",
89
"license": "MIT",

renderStylingSheet.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @copyright 2015, Andrey Popp
3+
*/
4+
5+
var Styling = require('./Styling');
6+
var renderStyling = require('./renderStyling');
7+
8+
function renderStylingSheet(sheet) {
9+
var stylesheet = [];
10+
for (var key in sheet) {
11+
if (sheet.hasOwnProperty(key)) {
12+
var styling = sheet[key];
13+
if (Styling.is(styling)) {
14+
stylesheet = stylesheet.concat(renderStyling(key, styling));
15+
}
16+
}
17+
}
18+
return stylesheet.join('\n\n');
19+
}
20+
21+
module.exports = renderStylingSheet;

0 commit comments

Comments
 (0)