@@ -5,7 +5,7 @@ var genId = require('./utils/gen-id')
5
5
var querystring = require ( 'querystring' )
6
6
var loaderUtils = require ( 'loader-utils' )
7
7
var normalize = require ( './utils/normalize' )
8
- var hasLoader = require ( './utils/has-loader ' )
8
+ var tryRequire = require ( './utils/try-require ' )
9
9
10
10
// internal lib loaders
11
11
var selectorPath = normalize . lib ( 'selector' )
@@ -19,8 +19,8 @@ var styleLoaderPath = normalize.dep('vue-style-loader')
19
19
var hotReloadAPIPath = normalize . dep ( 'vue-hot-reload-api' )
20
20
21
21
// check whether default js loader exists
22
- var hasBabel = hasLoader ( 'babel' )
23
- var hasBuble = hasLoader ( 'buble' )
22
+ var hasBabel = ! ! tryRequire ( 'babel-loader ' )
23
+ var hasBuble = ! ! tryRequire ( 'buble-loader ' )
24
24
25
25
var rewriterInjectRE = / \b ( c s s (?: - l o a d e r ) ? (?: \? [ ^ ! ] + ) ? ) (?: ! | $ ) /
26
26
@@ -83,7 +83,9 @@ module.exports = function (content) {
83
83
84
84
var defaultLoaders = {
85
85
html : templateCompilerPath + templateCompilerOptions ,
86
- css : styleLoaderPath + '!' + 'css-loader' + cssLoaderOptions ,
86
+ css : options . extractCSS
87
+ ? getCSSExtractLoader ( )
88
+ : styleLoaderPath + '!' + 'css-loader' + cssLoaderOptions ,
87
89
js : hasBuble ? ( 'buble-loader' + bubleOptions ) : hasBabel ? 'babel-loader' : ''
88
90
}
89
91
@@ -190,19 +192,29 @@ module.exports = function (content) {
190
192
191
193
function getRawLoaderString ( type , part , index , scoped ) {
192
194
var lang = part . lang || defaultLang [ type ]
193
- var loader = loaders [ lang ]
194
195
195
196
var styleCompiler = ''
196
197
if ( type === 'styles' ) {
198
+ // style compiler that needs to be applied for all styles
197
199
styleCompiler = styleCompilerPath + '?' + JSON . stringify ( {
198
200
// a marker for vue-style-loader to know that this is an import from a vue file
199
201
vue : true ,
200
202
id : moduleId ,
201
203
scoped : ! ! scoped ,
202
204
hasInlineConfig : ! ! query . postcss
203
205
} ) + '!'
206
+ // normalize scss/sass
207
+ if ( lang === 'sass' ) {
208
+ lang = 'sass?indentedSyntax'
209
+ } else if ( lang === 'scss' ) {
210
+ lang = 'sass'
211
+ }
204
212
}
205
213
214
+ var loader = options . extractCSS
215
+ ? loaders [ lang ] || getCSSExtractLoader ( lang )
216
+ : loaders [ lang ]
217
+
206
218
var injectString = ( type === 'script' && query . inject )
207
219
? 'inject-loader!'
208
220
: ''
@@ -252,7 +264,7 @@ module.exports = function (content) {
252
264
253
265
// sass => sass-loader
254
266
// sass-loader => sass-loader
255
- // sass?indentedsyntax !css => sass-loader?indentedSyntax!css-loader
267
+ // sass?indentedSyntax !css => sass-loader?indentedSyntax!css-loader
256
268
function ensureLoader ( lang ) {
257
269
return lang . split ( '!' ) . map ( function ( loader ) {
258
270
return loader . replace ( / ^ ( [ \w - ] + ) ( \? .* ) ? / , function ( _ , name , query ) {
@@ -275,6 +287,32 @@ module.exports = function (content) {
275
287
}
276
288
}
277
289
290
+ function getCSSExtractLoader ( lang ) {
291
+ var extract
292
+ var op = options . extractCSS
293
+ // extractCSS option is an instance of ExtractTextPlugin
294
+ if ( typeof op . extract === 'function' ) {
295
+ extract = op . extract
296
+ } else {
297
+ var plugin = tryRequire ( 'extract-text-webpack-plugin' )
298
+ if ( ! plugin ) {
299
+ throw new Error (
300
+ '[vue-loader] extractCSS: true requires extract-text-webpack-plugin ' +
301
+ 'as a peer dependency.'
302
+ )
303
+ } else {
304
+ extract = plugin . extract
305
+ }
306
+ }
307
+ var langLoader = lang
308
+ ? ensureBang ( ensureLoader ( lang ) )
309
+ : ''
310
+ return extract ( {
311
+ use : 'css-loader' + cssLoaderOptions + '!' + langLoader ,
312
+ fallback : 'vue-style-loader'
313
+ } )
314
+ }
315
+
278
316
var output = ''
279
317
var parts = parse ( content , fileName , this . sourceMap )
280
318
var hasScoped = parts . styles . some ( function ( s ) { return s . scoped } )
0 commit comments