2
2
MIT License http://www.opensource.org/licenses/mit-license.php
3
3
Author Tobias Koppers @sokra
4
4
*/
5
- var RawSource = require ( "webpack/lib/RawSource " ) ;
5
+ var SourceMapSource = require ( "webpack/lib/SourceMapSource " ) ;
6
6
var Template = require ( "webpack/lib/Template" ) ;
7
7
var async = require ( "async" ) ;
8
+ var SourceNode = require ( "source-map" ) . SourceNode ;
9
+ var SourceMapConsumer = require ( "source-map" ) . SourceMapConsumer ;
10
+ var ModuleFilenameHelpers = require ( "webpack/lib/ModuleFilenameHelpers" ) ;
8
11
9
12
var nextId = 0 ;
10
13
@@ -41,6 +44,17 @@ ExtractTextPlugin.extract = function(before, loader) {
41
44
}
42
45
} ;
43
46
47
+ ExtractTextPlugin . prototype . applyAdditionalInformation = function ( node , info ) {
48
+ if ( info . length === 1 && info [ 0 ] ) {
49
+ node = new SourceNode ( null , null , null , [
50
+ "@media " + info [ 0 ] + " {" ,
51
+ node ,
52
+ "}"
53
+ ] ) ;
54
+ }
55
+ return node ;
56
+ } ;
57
+
44
58
ExtractTextPlugin . prototype . loader = function ( options ) {
45
59
options = JSON . parse ( JSON . stringify ( options || { } ) ) ;
46
60
options . id = this . id ;
@@ -67,28 +81,28 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
67
81
var options = this . options ;
68
82
compiler . plugin ( "this-compilation" , function ( compilation ) {
69
83
compilation . plugin ( "normal-module-loader" , function ( loaderContext , module ) {
70
- loaderContext [ __dirname ] = function ( text , opt ) {
71
- if ( typeof text !== "string" && text !== null )
84
+ loaderContext [ __dirname ] = function ( content , opt ) {
85
+ if ( ! Array . isArray ( content ) && content !== null )
72
86
throw new Error ( "Exported value is not a string." ) ;
73
87
module . meta [ __dirname ] = {
74
- text : text ,
88
+ content : content ,
75
89
options : opt
76
90
} ;
77
91
return options . allChunks || module . meta [ __dirname + "/extract" ] ;
78
92
} ;
79
93
} . bind ( this ) ) ;
80
- var texts ;
94
+ var contents ;
81
95
var filename = this . filename ;
82
96
var id = this . id ;
83
97
compilation . plugin ( "optimize-tree" , function ( chunks , modules , callback ) {
84
- texts = [ ] ;
98
+ contents = [ ] ;
85
99
async . forEach ( chunks , function ( chunk , callback ) {
86
100
var shouldExtract = ! ! ( options . allChunks || chunk . initial ) ;
87
- var text = [ ] ;
101
+ var content = [ ] ;
88
102
async . forEach ( chunk . modules . slice ( ) , function ( module , callback ) {
89
103
var meta = module . meta && module . meta [ __dirname ] ;
90
104
if ( meta ) {
91
- var wasExtracted = typeof meta . text === "string" ;
105
+ var wasExtracted = Array . isArray ( meta . content ) ;
92
106
if ( shouldExtract !== wasExtracted ) {
93
107
module . meta [ __dirname + "/extract" ] = shouldExtract
94
108
compilation . rebuildModule ( module , function ( err ) {
@@ -97,25 +111,25 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
97
111
return callback ( ) ;
98
112
}
99
113
meta = module . meta [ __dirname ] ;
100
- if ( typeof meta . text !== "string" ) {
101
- var err = new Error ( module . identifier ( ) + " doesn't export text " ) ;
114
+ if ( ! Array . isArray ( meta . content ) ) {
115
+ var err = new Error ( module . identifier ( ) + " doesn't export content " ) ;
102
116
compilation . errors . push ( err ) ;
103
117
return callback ( ) ;
104
118
}
105
- if ( meta . text ) text . push ( meta . text ) ;
119
+ if ( meta . content ) content . push ( meta . content ) ;
106
120
callback ( ) ;
107
121
} ) ;
108
122
} else {
109
- if ( meta . text ) text . push ( meta . text ) ;
123
+ if ( meta . content ) content . push ( meta . content ) ;
110
124
callback ( ) ;
111
125
}
112
126
} else callback ( ) ;
113
127
} , function ( err ) {
114
128
if ( err ) return callback ( err ) ;
115
- if ( text . length > 0 ) {
116
- texts . push ( {
129
+ if ( content . length > 0 ) {
130
+ contents . push ( {
117
131
chunk : chunk ,
118
- text : text
132
+ content : content
119
133
} ) ;
120
134
}
121
135
callback ( ) ;
@@ -127,19 +141,35 @@ ExtractTextPlugin.prototype.apply = function(compiler) {
127
141
} ) ;
128
142
compilation . plugin ( "additional-assets" , function ( callback ) {
129
143
var assetContents = { } ;
130
- texts . forEach ( function ( item ) {
144
+ contents . forEach ( function ( item ) {
131
145
var chunk = item . chunk ;
132
146
var file = filename
133
147
. replace ( Template . REGEXP_NAME , chunk . name || chunk . id )
134
148
. replace ( Template . REGEXP_HASH , compilation . hash )
135
149
. replace ( Template . REGEXP_CHUNKHASH , chunk . renderedHash ) ;
136
- assetContents [ file ] = ( assetContents [ file ] || [ ] ) . concat ( item . text ) ;
150
+ assetContents [ file ] = ( assetContents [ file ] || [ ] ) . concat ( item . content ) ;
151
+ chunk . files . push ( file ) ;
137
152
} ) ;
138
153
Object . keys ( assetContents ) . forEach ( function ( file ) {
139
- var text = assetContents [ file ] . join ( "" ) ;
140
- this . assets [ file ] = new RawSource ( text ) ;
154
+ var contained = { } ;
155
+ var content = assetContents [ file ] . reduce ( function ( arr , items ) {
156
+ return arr . concat ( items ) ;
157
+ } , [ ] ) . filter ( function ( item ) {
158
+ if ( contained [ item [ 0 ] ] ) return false ;
159
+ contained [ item [ 0 ] ] = true ;
160
+ return true ;
161
+ } ) . map ( function ( item ) {
162
+ var css = item [ 1 ] ;
163
+ var contents = item . slice ( 1 ) . filter ( function ( i ) { return typeof i === "string" ; } ) ;
164
+ var sourceMap = typeof item [ item . length - 1 ] === "object" ? item [ item . length - 1 ] : undefined ;
165
+ var text = contents . shift ( ) ;
166
+ var node = sourceMap ? SourceNode . fromStringWithSourceMap ( text , new SourceMapConsumer ( sourceMap ) ) : new SourceNode ( null , null , null , text ) ;
167
+ return this . applyAdditionalInformation ( node , contents ) ;
168
+ } . bind ( this ) ) ;
169
+ var strAndMap = new SourceNode ( null , null , null , content ) . toStringWithSourceMap ( ) ;
170
+ compilation . assets [ file ] = new SourceMapSource ( strAndMap . code , file , strAndMap . map . toJSON ( ) ) ;
141
171
} . bind ( this ) ) ;
142
172
callback ( ) ;
143
- } ) ;
173
+ } . bind ( this ) ) ;
144
174
} . bind ( this ) ) ;
145
175
} ;
0 commit comments