Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 62 additions & 11 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ module.exports = function (content) {
// disable all configuration loaders
'!!' +
// get loader string for pre-processors
getLoaderString(type, part, scoped) +
getLoaderString(type, part, index, scoped) +
// select the corresponding part from the vue file
getSelectorString(type, index || 0) +
// the url to the actual vuefile
Expand All @@ -94,17 +94,41 @@ module.exports = function (content) {
function getRequireForImportString (type, impt, scoped) {
return loaderUtils.stringifyRequest(loaderContext,
'!!' +
getLoaderString(type, impt, scoped) +
getLoaderString(type, impt, -1, scoped) +
impt.src
)
}

function getLoaderString (type, part, scoped) {
function addCssModulesToLoader (loader, part, index) {
if (!part.module) return loader
return loader.replace(/((?:^|!)css(?:-loader)?)(\?[^!]*)?/, function (m, $1, $2) {
// $1: !css-loader
// $2: ?a=b
var query = loaderUtils.parseQuery($2)
query.modules = true
query.importLoaders = true
query.localIdentName = query.localIdentName || '[hash:base64:7]'
if (index !== -1) {
// Note:
// Class name is generated according to its filename.
// Different <style> tags in the same .vue file may generate same names.
// Append `_[index]` to class name to avoid this.
query.localIdentName += '_' + index
}
return $1 + '?' + JSON.stringify(query)
})
}

function getLoaderString (type, part, index, scoped) {
var lang = part.lang || defaultLang[type]
var loader = loaders[lang]
var rewriter = type === 'styles' ? styleRewriter + (scoped ? '&scoped=true!' : '!') : ''
var isStyles = type === 'styles'
var rewriter = isStyles ? styleRewriter + (scoped ? '&scoped=true!' : '!') : ''
var injectString = (type === 'script' && query.inject) ? 'inject!' : ''
if (loader !== undefined) {
if (isStyles) {
loader = addCssModulesToLoader(loader, part, index)
}
// inject rewriter before css/html loader for
// extractTextPlugin use cases
if (rewriterInjectRE.test(loader)) {
Expand All @@ -121,7 +145,7 @@ module.exports = function (content) {
case 'template':
return defaultLoaders.html + '!' + templateLoaderPath + '?raw&engine=' + lang + '!'
case 'styles':
return defaultLoaders.css + '!' + rewriter + lang + '!'
return addCssModulesToLoader(defaultLoaders.css, part, index) + '!' + rewriter + lang + '!'
case 'script':
return injectString + lang + '!'
}
Expand All @@ -144,15 +168,31 @@ module.exports = function (content) {

var parts = parse(content, fileName, this.sourceMap)
var hasScoped = parts.styles.some(function (s) { return s.scoped })
var output = 'var __vue_exports__, __vue_options__\n'
var hasModules = parts.styles.some(function (s) { return s.module })
var output = 'var __vue_exports__, __vue_options__'

output += hasModules ? ', __vue_cssmodules__ = {}\n' : '\n'

// add requires for styles
if (!isServer && parts.styles.length) {
output += '\n/* styles */\n'
var styles = parts.styles
if ((!isServer || hasModules) && styles.length) {
output += '/* styles */\n'

parts.styles.forEach(function (style, i) {
output += style.src
? getRequireForImport('styles', style, style.scoped)
: getRequire('styles', style, i, style.scoped)
var module = style.module

if (!isServer || module) {
var requireString = style.src
? getRequireForImport('styles', style, style.scoped)
: getRequire('styles', style, i, style.scoped)

if (module) {
var name = module === true ? 'style' : module
output += '__vue_cssmodules__["' + name + '"] = ' + requireString + '\n'
} else {
output += requireString
}
}
})
}

Expand Down Expand Up @@ -205,6 +245,17 @@ module.exports = function (content) {
exports += '__vue_options__._scopeId = "' + moduleId + '"\n'
}

// define css modules
if (hasModules) {
// inject style modules as computed properties
exports +=
'if (!__vue_options__.computed) __vue_options__.computed = {}\n' +
'Object.keys(__vue_cssmodules__).forEach(function (key) {\n' +
'var module = __vue_cssmodules__[key]\n' +
'__vue_options__.computed[key] = function () { return module }\n' +
'})\n'
}

if (!query.inject) {
output += exports
// hot reload
Expand Down