This commit is contained in:
chrosey
2017-09-13 07:52:34 +02:00
parent a1f16c37f4
commit 2340b0226b
24621 changed files with 2912161 additions and 149 deletions
+51
View File
@@ -0,0 +1,51 @@
// this module is a runtime utility for cleaner component module output and will
// be included in the final webpack user bundle
module.exports = function normalizeComponent (
rawScriptExports,
compiledTemplate,
scopeId,
cssModules
) {
var esModule
var scriptExports = rawScriptExports = rawScriptExports || {}
// ES6 modules interop
var type = typeof rawScriptExports.default
if (type === 'object' || type === 'function') {
esModule = rawScriptExports
scriptExports = rawScriptExports.default
}
// Vue.extend constructor export interop
var options = typeof scriptExports === 'function'
? scriptExports.options
: scriptExports
// render functions
if (compiledTemplate) {
options.render = compiledTemplate.render
options.staticRenderFns = compiledTemplate.staticRenderFns
}
// scopedId
if (scopeId) {
options._scopeId = scopeId
}
// inject cssModules
if (cssModules) {
var computed = Object.create(options.computed || null)
Object.keys(cssModules).forEach(function (key) {
var module = cssModules[key]
computed[key] = function () { return module }
})
options.computed = computed
}
return {
esModule: esModule,
exports: scriptExports,
options: options
}
}
+488
View File
@@ -0,0 +1,488 @@
var path = require('path')
var parse = require('./parser')
var genId = require('./utils/gen-id')
var normalize = require('./utils/normalize')
var loaderUtils = require('loader-utils')
var querystring = require('querystring')
// internal lib loaders
var selectorPath = normalize.lib('selector')
var styleCompilerPath = normalize.lib('style-compiler/index')
var templateCompilerPath = normalize.lib('template-compiler/index')
var templatePreprocessorPath = normalize.lib('template-compiler/preprocessor')
var componentNormalizerPath = normalize.lib('component-normalizer')
// dep loaders
var styleLoaderPath = normalize.dep('vue-style-loader')
var hotReloadAPIPath = normalize.dep('vue-hot-reload-api')
var hasBabel = false
try {
hasBabel = !!require('babel-loader')
} catch (e) {}
var hasBuble = false
try {
hasBuble = !!require('buble-loader')
} catch (e) {}
var rewriterInjectRE = /\b(css(?:-loader)?(?:\?[^!]+)?)(?:!|$)/
var defaultLang = {
template: 'html',
styles: 'css',
script: 'js'
}
// When extracting parts from the source vue file, we want to apply the
// loaders chained before vue-loader, but exclude some loaders that simply
// produces side effects such as linting.
function getRawRequest (context, excludedPreLoaders) {
excludedPreLoaders = excludedPreLoaders || /eslint-loader/
return loaderUtils.getRemainingRequest({
resource: context.resource,
loaderIndex: context.loaderIndex,
loaders: context.loaders.filter(loader => !excludedPreLoaders.test(loader.path))
})
}
module.exports = function (content) {
this.cacheable()
var isServer = this.target === 'node'
var isProduction = this.minimize || process.env.NODE_ENV === 'production'
var loaderContext = this
var query = loaderUtils.getOptions(this) || {}
var options = this.options.__vueOptions__ = Object.assign({}, this.options.vue, this.vue, query)
var rawRequest = getRawRequest(this, options.excludedPreLoaders)
var filePath = this.resourcePath
var fileName = path.basename(filePath)
var context = (this._compiler && this._compiler.context) || this.options.context || process.cwd()
var moduleId = 'data-v-' + genId(filePath, context, options.hashKey)
var cssLoaderOptions = ''
if (!isProduction && this.sourceMap && options.cssSourceMap !== false) {
cssLoaderOptions += '?sourceMap'
}
if (isProduction) {
cssLoaderOptions += (cssLoaderOptions ? '&' : '?') + 'minimize'
}
var bubleOptions = hasBuble && options.buble
? '?' + JSON.stringify(options.buble)
: ''
var templateCompilerOptions = '?' + JSON.stringify({
id: moduleId,
transformToRequire: options.transformToRequire,
preserveWhitespace: options.preserveWhitespace,
buble: options.buble,
// only pass compilerModules if it's a path string
compilerModules: typeof options.compilerModules === 'string'
? options.compilerModules
: undefined
})
var defaultLoaders = {
html: templateCompilerPath + templateCompilerOptions,
css: styleLoaderPath + '!' + 'css-loader' + cssLoaderOptions,
js: hasBuble ? ('buble-loader' + bubleOptions) : hasBabel ? 'babel-loader' : ''
}
// check if there are custom loaders specified via
// webpack config, otherwise use defaults
var loaders = Object.assign({}, defaultLoaders, options.loaders)
var preLoaders = options.preLoaders || {}
var postLoaders = options.postLoaders || {}
function getRequire (type, part, index, scoped) {
return 'require(' +
getRequireString(type, part, index, scoped) +
')'
}
function getRequireString (type, part, index, scoped) {
return loaderUtils.stringifyRequest(loaderContext,
// disable all configuration loaders
'!!' +
// get loader string for pre-processors
getLoaderString(type, part, index, scoped) +
// select the corresponding part from the vue file
getSelectorString(type, index || 0) +
// the url to the actual vue file, including remaining requests
rawRequest
)
}
function getRequireForImport (type, impt, scoped) {
return 'require(' +
getRequireForImportString(type, impt, scoped) +
')'
}
function getRequireForImportString (type, impt, scoped) {
return loaderUtils.stringifyRequest(loaderContext,
'!!' +
getLoaderString(type, impt, -1, scoped) +
impt.src
)
}
function addCssModulesToLoader (loader, part, index) {
if (!part.module) return loader
var option = options.cssModules || {}
var DEFAULT_OPTIONS = {
modules: true,
importLoaders: true
}
var OPTIONS = {
localIdentName: '[hash:base64]'
}
return loader.replace(/((?:^|!)css(?:-loader)?)(\?[^!]*)?/, function (m, $1, $2) {
// $1: !css-loader
// $2: ?a=b
var query = loaderUtils.parseQuery($2 || '?')
Object.assign(query, OPTIONS, option, DEFAULT_OPTIONS)
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 buildCustomBlockLoaderString (attrs) {
var noSrcAttrs = Object.assign({}, attrs)
delete noSrcAttrs.src
var qs = querystring.stringify(noSrcAttrs)
return qs ? '?' + qs : qs
}
// stringify an Array of loader objects
function stringifyLoaders (loaders) {
return loaders.map(function (obj) {
return obj && typeof obj === 'object' && typeof obj.loader === 'string'
? obj.loader + (obj.options ? '?' + JSON.stringify(obj.options) : '')
: obj
}).join('!')
}
function getLoaderString (type, part, index, scoped) {
var loader = getRawLoaderString(type, part, index, scoped)
var lang = getLangString(type, part)
if (preLoaders[lang]) {
loader = loader + ensureBang(preLoaders[lang])
}
if (postLoaders[lang]) {
loader = ensureBang(postLoaders[lang]) + loader
}
return loader
}
function getLangString (type, part) {
if (type === 'script' || type === 'template' || type === 'styles') {
return part.lang || defaultLang[type]
} else {
return type
}
}
function getRawLoaderString (type, part, index, scoped) {
var lang = part.lang || defaultLang[type]
var loader = loaders[lang]
var styleCompiler = ''
if (type === 'styles') {
styleCompiler = styleCompilerPath + '?' + JSON.stringify({
id: moduleId,
scoped: !!scoped,
hasInlineConfig: !!query.postcss
}) + '!'
}
var injectString = (type === 'script' && query.inject)
? 'inject-loader!'
: ''
if (loader != null) {
if (Array.isArray(loader)) {
loader = stringifyLoaders(loader)
} else if (typeof loader === 'object') {
loader = stringifyLoaders([loader])
}
if (type === 'styles') {
// add css modules
loader = addCssModulesToLoader(loader, part, index)
// inject rewriter before css loader for extractTextPlugin use cases
if (rewriterInjectRE.test(loader)) {
loader = loader.replace(rewriterInjectRE, function (m, $1) {
return ensureBang($1) + styleCompiler
})
} else {
loader = ensureBang(loader) + styleCompiler
}
}
// if user defines custom loaders for html, add template compiler to it
if (type === 'template' && loader.indexOf(defaultLoaders.html) < 0) {
loader = defaultLoaders.html + '!' + loader
}
return injectString + ensureBang(loader)
} else {
// unknown lang, infer the loader to be used
switch (type) {
case 'template':
return defaultLoaders.html + '!' + templatePreprocessorPath + '?raw&engine=' + lang + '!'
case 'styles':
loader = addCssModulesToLoader(defaultLoaders.css, part, index)
return loader + '!' + styleCompiler + ensureBang(ensureLoader(lang))
case 'script':
return injectString + ensureBang(ensureLoader(lang))
default:
loader = loaders[type]
if (Array.isArray(loader)) {
loader = stringifyLoaders(loader)
}
return ensureBang(loader + buildCustomBlockLoaderString(part.attrs))
}
}
}
// sass => sass-loader
// sass-loader => sass-loader
// sass?indentedsyntax!css => sass-loader?indentedSyntax!css-loader
function ensureLoader (lang) {
return lang.split('!').map(function (loader) {
return loader.replace(/^([\w-]+)(\?.*)?/, function (_, name, query) {
return (/-loader$/.test(name) ? name : (name + '-loader')) + (query || '')
})
}).join('!')
}
function getSelectorString (type, index) {
return selectorPath +
'?type=' + ((type === 'script' || type === 'template' || type === 'styles') ? type : 'customBlocks') +
'&index=' + index + '!'
}
function ensureBang (loader) {
if (loader.charAt(loader.length - 1) !== '!') {
return loader + '!'
} else {
return loader
}
}
var output = ''
var parts = parse(content, fileName, this.sourceMap)
var hasScoped = parts.styles.some(function (s) { return s.scoped })
// css modules
var cssModules
// add requires for styles
if (parts.styles.length) {
output += '\n/* styles */\n'
var hasModules = false
parts.styles.forEach(function (style, i) {
// require style
var requireString = style.src
? getRequireForImport('styles', style, style.scoped)
: getRequire('styles', style, i, style.scoped)
var moduleName = (style.module === true) ? '$style' : style.module
// setCssModule
if (moduleName) {
if (!cssModules) {
cssModules = {}
}
if (!hasModules) {
hasModules = true
output += 'var cssModules = {}\n'
}
if (moduleName in cssModules) {
loaderContext.emitError('CSS module name "' + moduleName + '" is not unique!')
output += requireString
} else {
cssModules[moduleName] = true
// `(vue-)style-loader` exposes the name-to-hash map directly
// `css-loader` exposes it in `.locals`
// add `.locals` if the user configured to not use style-loader.
if (requireString.indexOf('style-loader') < 0) {
requireString += '.locals'
}
output += 'cssModules["' + moduleName + '"] = ' + requireString + '\n'
}
} else {
output += requireString + '\n'
}
})
output += '\n'
}
// we require the component normalizer function, and call it like so:
// normalizeComponent(
// scriptExports,
// compiledTemplate,
// scopeId,
// cssModules
// )
output += 'var Component = require(' +
loaderUtils.stringifyRequest(loaderContext, '!' + componentNormalizerPath) +
')(\n'
// <script>
output += ' /* script */\n '
var script = parts.script
if (script) {
output += script.src
? getRequireForImport('script', script)
: getRequire('script', script)
// inject loader interop
if (query.inject) {
output += '(injections)'
}
} else {
output += 'null'
}
output += ',\n'
// <template>
output += ' /* template */\n '
var template = parts.template
if (template) {
output += template.src
? getRequireForImport('template', template)
: getRequire('template', template)
} else {
output += 'null'
}
output += ',\n'
// scopeId
output += ' /* scopeId */\n '
output += (hasScoped ? JSON.stringify(moduleId) : 'null') + ',\n'
// cssModules
output += ' /* cssModules */\n '
if (cssModules) {
// inject style modules as computed properties
output += 'cssModules'
} else {
output += 'null'
}
output += '\n'
// close normalizeComponent call
output += ')\n'
// development-only code
if (!isProduction) {
// add filename in dev
output += 'Component.options.__file = ' + JSON.stringify(filePath) + '\n'
// check named exports
output +=
'if (Component.esModule && Object.keys(Component.esModule).some(function (key) {' +
'return key !== "default" && key !== "__esModule"' +
'})) {' +
'console.error("named exports are not supported in *.vue files.")' +
'}\n'
// check functional components used with templates
if (template) {
output +=
'if (Component.options.functional) {' +
'console.error("' +
'[vue-loader] ' + fileName + ': functional components are not ' +
'supported with templates, they should use render functions.' +
'")}\n'
}
}
// add requires for customBlocks
if (parts.customBlocks && parts.customBlocks.length) {
var addedPrefix = false
parts.customBlocks.forEach(function (customBlock, i) {
if (loaders[customBlock.type]) {
// require customBlock
customBlock.src = customBlock.attrs.src
var requireString = customBlock.src
? getRequireForImport(customBlock.type, customBlock)
: getRequire(customBlock.type, customBlock, i)
if (!addedPrefix) {
output += '\n/* customBlocks */\n'
addedPrefix = true
}
output +=
'var customBlock = ' + requireString + '\n' +
'if (typeof customBlock === "function") {' +
'customBlock(Component)' +
'}\n'
}
})
output += '\n'
}
if (!query.inject) {
// hot reload
if (
!isServer &&
!isProduction &&
(parts.script || parts.template)
) {
output +=
'\n/* hot reload */\n' +
'if (module.hot) {(function () {\n' +
' var hotAPI = require("' + hotReloadAPIPath + '")\n' +
' hotAPI.install(require("vue"), false)\n' +
' if (!hotAPI.compatible) return\n' +
' module.hot.accept()\n' +
' if (!module.hot.data) {\n' +
// initial insert
' hotAPI.createRecord("' + moduleId + '", Component.options)\n' +
' } else {\n'
// update
if (cssModules) {
output +=
' if (module.hot.data.cssModules && JSON.stringify(module.hot.data.cssModules) !== JSON.stringify(cssModules)) {\n' +
' delete Component.options._Ctor\n' +
' }\n'
}
output +=
' hotAPI.reload("' + moduleId + '", Component.options)\n' +
' }\n'
if (cssModules) {
// save cssModules
output +=
' module.hot.dispose(function (data) {\n' +
' data.cssModules = cssModules\n' +
' })\n'
}
output += '})()}\n'
}
// final export
if (options.esModule) {
output += '\nexports.__esModule = true;\nexports["default"] = Component.exports\n'
} else {
output += '\nmodule.exports = Component.exports\n'
}
} else {
// inject-loader support
output =
'\n/* dependency injection */\n' +
'module.exports = function (injections) {\n' + output + '\n' +
'\nreturn Component.exports\n}'
}
// done
return output
}
+59
View File
@@ -0,0 +1,59 @@
var compiler = require('vue-template-compiler')
var cache = require('lru-cache')(100)
var hash = require('hash-sum')
var SourceMapGenerator = require('source-map').SourceMapGenerator
var splitRE = /\r?\n/g
var emptyRE = /^(?:\/\/)?\s*$/
module.exports = function (content, filename, needMap) {
var cacheKey = hash(filename + content)
// source-map cache busting for hot-reloadded modules
var filenameWithHash = filename + '?' + cacheKey
var output = cache.get(cacheKey)
if (output) return output
output = compiler.parseComponent(content, { pad: 'line' })
if (needMap) {
if (output.script && !output.script.src) {
output.script.map = generateSourceMap(
filenameWithHash,
content,
output.script.content
)
}
if (output.styles) {
output.styles.forEach(style => {
if (!style.src) {
style.map = generateSourceMap(
filenameWithHash,
content,
style.content
)
}
})
}
}
cache.set(cacheKey, output)
return output
}
function generateSourceMap (filename, source, generated) {
var map = new SourceMapGenerator()
map.setSourceContent(filename, source)
generated.split(splitRE).forEach((line, index) => {
if (!emptyRE.test(line)) {
map.addMapping({
source: filename,
original: {
line: index + 1,
column: 0
},
generated: {
line: index + 1,
column: 0
}
})
}
})
return map.toJSON()
}
+19
View File
@@ -0,0 +1,19 @@
// this is a utility loader that takes a *.vue file, parses it and returns
// the requested language block, e.g. the content inside <template>, for
// further processing.
var path = require('path')
var parse = require('./parser')
var loaderUtils = require('loader-utils')
module.exports = function (content) {
this.cacheable()
var query = loaderUtils.getOptions(this) || {}
var filename = path.basename(this.resourcePath)
var parts = parse(content, filename, this.sourceMap)
var part = parts[query.type]
if (Array.isArray(part)) {
part = part[query.index]
}
this.callback(null, part.content, part.map)
}
+68
View File
@@ -0,0 +1,68 @@
var postcss = require('postcss')
var loaderUtils = require('loader-utils')
var loadPostcssConfig = require('./load-postcss-config')
var trim = require('./plugins/trim')
var scopeId = require('./plugins/scope-id')
module.exports = function (css, map) {
this.cacheable()
var cb = this.async()
var query = loaderUtils.getOptions(this) || {}
var vueOptions = this.options.__vueOptions__
if (!vueOptions) {
if (query.hasInlineConfig) {
this.emitError(
`\n [vue-loader] It seems you are using HappyPack with inline postcss ` +
`options for vue-loader. This is not supported because loaders running ` +
`in different threads cannot share non-serializable options. ` +
`It is recommended to use a postcss config file instead.\n` +
`\n See http://vue-loader.vuejs.org/en/features/postcss.html#using-a-config-file for more details.\n`
)
}
vueOptions = Object.assign({}, this.options.vue, this.vue)
}
// use the same config loading interface as postcss-loader
loadPostcssConfig(vueOptions.postcss).then(config => {
var plugins = [trim].concat(config.plugins)
var options = Object.assign({
to: this.resourcePath,
from: this.resourcePath,
map: false
}, config.options)
// add plugin for vue-loader scoped css rewrite
if (query.scoped) {
plugins.push(scopeId({ id: query.id }))
}
// source map
if (
this.sourceMap &&
!this.minimize &&
vueOptions.cssSourceMap !== false &&
process.env.NODE_ENV !== 'production' &&
!options.map
) {
options.map = {
inline: false,
annotation: false,
prev: map
}
}
return postcss(plugins)
.process(css, options)
.then(function (result) {
var map = result.map && result.map.toJSON()
cb(null, result.css, map)
return null // silence bluebird warning
})
}).catch(e => {
console.log(e)
cb(e)
})
}
+45
View File
@@ -0,0 +1,45 @@
var load = require('postcss-load-config')
var loaded
function isObject (val) {
return val && typeof val === 'object'
}
module.exports = function loadPostcssConfig (inlineConfig) {
if (process.env.VUE_LOADER_TEST || !loaded) {
loaded = load({}, null, { argv: false }).catch(() => {
// postcss-load-config throws error when no config file is found,
// but for us it's optional.
})
}
return loaded.then(config => {
var plugins = []
var options = {}
// inline postcss options for vue-loader
if (typeof inlineConfig === 'function') {
inlineConfig = inlineConfig.call(this, this)
}
if (Array.isArray(inlineConfig)) {
plugins = inlineConfig
} else if (isObject(inlineConfig)) {
plugins = inlineConfig.plugins || []
options = inlineConfig.options || {}
}
// merge postcss config file
if (config && config.plugins) {
plugins = plugins.concat(config.plugins)
}
if (config && config.options) {
options = Object.assign({}, config.options, options)
}
return {
plugins,
options
}
})
}
+27
View File
@@ -0,0 +1,27 @@
var postcss = require('postcss')
var selectorParser = require('postcss-selector-parser')
module.exports = postcss.plugin('add-id', function (opts) {
return function (root) {
root.each(function rewriteSelector (node) {
if (!node.selector) {
// handle media queries
if (node.type === 'atrule' && node.name === 'media') {
node.each(rewriteSelector)
}
return
}
node.selector = selectorParser(function (selectors) {
selectors.each(function (selector) {
var node = null
selector.each(function (n) {
if (n.type !== 'pseudo') node = n
})
selector.insertAfter(node, selectorParser.attribute({
attribute: opts.id
}))
})
}).process(node.selector).result
})
}
})
+11
View File
@@ -0,0 +1,11 @@
var postcss = require('postcss')
module.exports = postcss.plugin('trim', function (opts) {
return function (css) {
css.walk(function (node) {
if (node.type === 'rule' || node.type === 'atrule') {
node.raws.before = node.raws.after = '\n'
}
})
}
})
+81
View File
@@ -0,0 +1,81 @@
var loaderUtils = require('loader-utils')
var normalize = require('../utils/normalize')
var compiler = require('vue-template-compiler')
var beautify = require('js-beautify').js_beautify
var transpile = require('vue-template-es2015-compiler')
var hotReloadAPIPath = normalize.dep('vue-hot-reload-api')
var transformRequire = require('./modules/transform-require')
module.exports = function (html) {
this.cacheable()
var isServer = this.target === 'node'
var isProduction = this.minimize || process.env.NODE_ENV === 'production'
var vueOptions = this.options.__vueOptions__ || {}
var options = loaderUtils.getOptions(this) || {}
var defaultModules = [transformRequire(options.transformToRequire)]
var userModules = vueOptions.compilerModules || options.compilerModules
// for HappyPack cross-process use cases
if (typeof userModules === 'string') {
userModules = require(userModules)
}
var compilerOptions = {
preserveWhitespace: options.preserveWhitespace,
modules: defaultModules.concat(userModules || [])
}
var compiled = compiler.compile(html, compilerOptions)
// tips
if (compiled.tips && compiled.tips.length) {
compiled.tips.forEach(tip => {
this.emitWarning(tip)
})
}
var code
if (compiled.errors && compiled.errors.length) {
this.emitError(
`\n Error compiling template:\n${pad(html)}\n` +
compiled.errors.map(e => ` - ${e}`).join('\n') + '\n'
)
code = 'module.exports={render:function(){},staticRenderFns:[]}'
} else {
var bubleOptions = options.buble
code = transpile('module.exports={' +
'render:' + toFunction(compiled.render) + ',' +
'staticRenderFns: [' + compiled.staticRenderFns.map(toFunction).join(',') + ']' +
'}', bubleOptions)
// mark with stripped (this enables Vue to use correct runtime proxy detection)
if (!isProduction && (
!bubleOptions ||
!bubleOptions.transforms ||
bubleOptions.transforms.stripWith !== false
)) {
code += `\nmodule.exports.render._withStripped = true`
}
}
// hot-reload
if (!isServer && !isProduction) {
code +=
'\nif (module.hot) {\n' +
' module.hot.accept()\n' +
' if (module.hot.data) {\n' +
' require("' + hotReloadAPIPath + '").rerender("' + options.id + '", module.exports)\n' +
' }\n' +
'}'
}
return code
}
function toFunction (code) {
return 'function (){' + beautify(code, {
indent_size: 2 // eslint-disable-line camelcase
}) + '}'
}
function pad (html) {
return html.split(/\r?\n/).map(line => ` ${line}`).join('\n')
}
@@ -0,0 +1,49 @@
// vue compiler module for transforming `<tag>:<attribute>` to `require`
var defaultOptions = {
img: 'src',
image: 'xlink:href'
}
module.exports = userOptions => {
var options = userOptions
? Object.assign({}, defaultOptions, userOptions)
: defaultOptions
return {
postTransformNode: node => {
transform(node, options)
}
}
}
function transform (node, options) {
for (var tag in options) {
if (node.tag === tag && node.attrs) {
var attributes = options[tag]
if (typeof attributes === 'string') {
node.attrs.some(attr => rewrite(attr, attributes))
} else if (Array.isArray(attributes)) {
attributes.forEach(item => node.attrs.some(attr => rewrite(attr, item)))
}
}
}
}
function rewrite (attr, name) {
if (attr.name === name) {
var value = attr.value
var isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"'
if (!isStatic) {
return
}
var firstChar = value.charAt(1)
if (firstChar === '.' || firstChar === '~') {
if (firstChar === '~') {
value = '"' + value.slice(2)
}
attr.value = `require(${value})`
}
return true
}
}
+50
View File
@@ -0,0 +1,50 @@
// loader for pre-processing templates with e.g. pug
var cons = require('consolidate')
var loaderUtils = require('loader-utils')
var extname = require('path').extname
module.exports = function (content) {
this.cacheable && this.cacheable()
var callback = this.async()
var opt = loaderUtils.getOptions(this) || {}
// this is never documented and should be deprecated
// but we'll keep it so we don't break stuff
var vue = this.options.__vueOptions__
if (vue && vue.template) {
for (var key in vue.template) {
opt[key] = vue.template[key]
}
}
function exportContent (content) {
if (opt.raw) {
callback(null, content)
} else {
callback(null, 'module.exports = ' + JSON.stringify(content))
}
}
// with no engine given, use the file extension as engine
if (!opt.engine) {
opt.engine = extname(this.request).substr(1).toLowerCase()
}
if (!cons[opt.engine]) {
return callback(new Error(
'Template engine \'' + opt.engine + '\' ' +
'isn\'t available in Consolidate.js'
))
}
// for relative includes
opt.filename = this.resourcePath
cons[opt.engine].render(content, opt, function (err, html) {
if (err) {
return callback(err)
}
exportContent(html)
})
}
+13
View File
@@ -0,0 +1,13 @@
// utility for generating a uid for each component file
// used in scoped CSS rewriting
var path = require('path')
var hash = require('hash-sum')
var cache = Object.create(null)
var sepRE = new RegExp(path.sep.replace('\\', '\\\\'), 'g')
module.exports = function genId (file, context, key) {
var contextPath = context.split(path.sep)
var rootId = contextPath[contextPath.length - 1]
file = rootId + '/' + path.relative(context, file).replace(sepRE, '/') + (key || '')
return cache[file] || (cache[file] = hash(file))
}
+19
View File
@@ -0,0 +1,19 @@
var IS_TEST = !!process.env.VUE_LOADER_TEST
var fs = require('fs')
var path = require('path')
exports.lib = function (file) {
return path.resolve(__dirname, '../', file)
}
exports.dep = function (dep) {
if (IS_TEST) {
return dep
} else if (fs.existsSync(path.resolve(__dirname, '../../node_modules', dep))) {
// npm 2 or npm linked
return 'vue-loader/node_modules/' + dep
} else {
// npm 3
return dep
}
}