1
1
import fs from 'fs' ;
2
2
import path from 'path' ;
3
3
import webpack from 'webpack' ;
4
+ import sources from 'webpack-sources' ;
5
+
6
+ const { RawSource, ConcatSource } = sources ;
4
7
5
8
const NS = path . dirname ( fs . realpathSync ( __filename ) ) ;
6
9
7
- class CssDependency {
8
- constructor ( { identifier, content, media, sourceMap } ) {
10
+ class CssDependency extends webpack . Dependency {
11
+ constructor ( { identifier, content, media, sourceMap } , context ) {
12
+ super ( ) ;
9
13
this . identifier = identifier ;
10
14
this . content = content ;
11
15
this . media = media ;
12
16
this . sourceMap = sourceMap ;
17
+ this . context = context ;
13
18
}
14
19
15
20
getResourceIdentifier ( ) {
@@ -23,16 +28,35 @@ class CssDependencyTemplate {
23
28
24
29
class CssModule extends webpack . Module {
25
30
constructor ( dependency ) {
26
- super ( NS ) ;
31
+ super ( NS , dependency . context ) ;
27
32
this . _identifier = dependency . identifier ;
28
33
this . content = dependency . content ;
29
34
this . media = dependency . media ;
30
35
this . sourceMap = dependency . sourceMap ;
31
36
}
32
37
38
+ source ( ) {
39
+ // TODO add webpack support for omitting js source
40
+ return new RawSource ( '// extracted by mini-css-extract-plugin' ) ;
41
+ }
42
+
43
+ size ( ) {
44
+ return 0 ;
45
+ }
46
+
33
47
identifier ( ) {
34
48
return `css-module ${ this . _identifier } ` ;
35
49
}
50
+
51
+ readableIdentifier ( requestShortener ) {
52
+ return `css-modules ${ requestShortener . shorten ( this . _identifier ) } ` ;
53
+ }
54
+
55
+ build ( options , compilation , resolver , fs , callback ) {
56
+ this . buildInfo = { } ;
57
+ this . buildMeta = { } ;
58
+ callback ( ) ;
59
+ }
36
60
}
37
61
38
62
class CssModuleFactory {
@@ -42,6 +66,16 @@ class CssModuleFactory {
42
66
}
43
67
44
68
class MiniCssExtractPlugin {
69
+ constructor ( options ) {
70
+ this . options = Object . assign ( {
71
+ filename : '[name].css' ,
72
+ } , options ) ;
73
+ if ( ! this . options . chunkFilename ) {
74
+ // TODO use webpack conversion style here
75
+ this . options . chunkFilename = this . options . filename ;
76
+ }
77
+ }
78
+
45
79
apply ( compiler ) {
46
80
compiler . hooks . thisCompilation . tap ( 'mini-css-extract-plugin' , ( compilation ) => {
47
81
compilation . hooks . normalModuleLoader . tap ( 'mini-css-extract-plugin' , ( lc , m ) => {
@@ -52,38 +86,44 @@ class MiniCssExtractPlugin {
52
86
throw new Error ( `Exported value was not extracted as an array: ${ JSON . stringify ( content ) } ` ) ;
53
87
}
54
88
for ( const line of content ) {
55
- module . addDependency ( new CssDependency ( line ) ) ;
89
+ module . addDependency ( new CssDependency ( line , m . context ) ) ;
56
90
}
57
91
} ;
58
92
} ) ;
59
93
compilation . dependencyFactories . set ( CssDependency , new CssModuleFactory ( ) ) ;
60
94
compilation . dependencyTemplates . set ( CssDependency , new CssDependencyTemplate ( ) ) ;
61
- compilation . mainTemplate . hooks . shouldRenderModuleForJavascript . tap ( 'mini-css-extract-plugin' , ( module ) => {
62
- if ( module . type === NS ) return false ;
63
- return undefined ;
64
- } ) ;
65
- compilation . chunkTemplate . hooks . shouldRenderModuleForJavascript . tap ( 'mini-css-extract-plugin' , ( module ) => {
66
- if ( module . type === NS ) return false ;
67
- return undefined ;
68
- } ) ;
69
- compilation . mainTemplate . hooks . renderManifest . tap ( 'mini-css-extract-plugin' , ( result , options ) => {
70
- const chunk = options . chunk ;
71
- const renderedContent = Array . from ( chunk . modulesIterable , m => module [ NS ] ) . filter ( Boolean ) ;
72
- if ( renderedContent . length > 0 ) {
95
+ compilation . mainTemplate . hooks . renderManifest . tap ( 'mini-css-extract-plugin' , ( result , { chunk } ) => {
96
+ const renderedModules = Array . from ( chunk . modulesIterable ) . filter ( module => module . type === NS ) ;
97
+ if ( renderedModules . length > 0 ) {
73
98
result . push ( {
74
- render : ( ) => this . renderContentAsset ( renderedContent ) ,
75
- filenameTemplate : filename ,
99
+ render : ( ) => this . renderContentAsset ( renderedModules ) ,
100
+ filenameTemplate : this . options . filename ,
76
101
pathOptions : {
77
- chunk
102
+ chunk,
78
103
} ,
79
- identifier : `extract-text-webpack-plugin.${ id } . ${ chunk . id } `
104
+ identifier : `extract-text-webpack-plugin.${ chunk . id } ` ,
80
105
} ) ;
81
106
}
82
107
} ) ;
83
108
} ) ;
84
109
}
110
+ renderContentAsset ( modules ) {
111
+ modules . sort ( ( a , b ) => a . index2 - b . index2 ) ;
112
+ // TODO put @import on top
113
+ const source = new ConcatSource ( ) ;
114
+ for ( const m of modules ) {
115
+ source . add ( m . content ) ;
116
+ source . add ( '\n' ) ;
117
+ if ( m . media ) {
118
+ source . prepend ( `@media ${ m . media } {\n` ) ;
119
+ source . add ( '}\n' ) ;
120
+ }
121
+ return source ;
122
+ }
123
+ return source ;
124
+ }
85
125
}
86
126
87
127
MiniCssExtractPlugin . loader = require . resolve ( './loader' ) ;
88
128
89
- module . exports = MiniCssExtractPlugin ;
129
+ export default MiniCssExtractPlugin ;
0 commit comments