Commit 939ee708 authored by Evan You's avatar Evan You

refactor: use more component compiler features

parent fb536909
const qs = require('querystring')
const loaderUtils = require('loader-utils')
const compiler = require('vue-template-compiler')
const transformAssetUrl = require('./modules/assetUrl')
const transformSrcset = require('./modules/srcset')
const { genTemplateHotReloadCode } = require('../hotReload')
const { compileTemplate } = require('vue-component-compiler')
......@@ -21,14 +19,11 @@ module.exports = function (source) {
const { id } = query
const isServer = loaderContext.target === 'node'
const isProduction = loaderContext.minimize || process.env.NODE_ENV === 'production'
const needsHotReload = !isServer && !isProduction && options.hotReload !== false
const defaultModules = [transformAssetUrl(options.transformAssetUrl), transformSrcset()]
const isFunctional = query.functional
const needsHotReload = !isServer && !isProduction && options.hotReload !== false
const userCompilerOptions = options.compilerOptions || {}
const compilerOptions = Object.assign({}, userCompilerOptions, {
const compilerOptions = Object.assign({}, options.compilerOptions, {
scopeId: query.scoped ? `data-v-${id}` : null,
modules: defaultModules.concat(userCompilerOptions.modules || []),
comments: query.comments
})
......@@ -47,6 +42,7 @@ module.exports = function (source) {
preprocessOptions,
// allow customizing behavior of vue-template-es2015-compiler
transpileOptions: options.transpileOptions,
transformAssetUrls: options.transformAssetUrls || true,
isProduction,
isFunctional,
optimizeSSR: isServer && options.optimizeSSR !== false
......
// vue compiler module for transforming `<tag>:<attribute>` to `require`
const urlToRequire = require('./urlToRequire')
const defaultOptions = {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
module.exports = userOptions => {
const options = userOptions
? Object.assign({}, defaultOptions, userOptions)
: defaultOptions
return {
postTransformNode: node => {
transform(node, options)
}
}
}
function transform (node, options) {
for (const tag in options) {
if ((tag === '*' || node.tag === tag) && node.attrs) {
const 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) {
const value = attr.value
// only transform static URLs
if (value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') {
attr.value = urlToRequire(value.slice(1, -1))
return true
}
}
}
// vue compiler module for transforming `img:srcset` to a number of `require`s
const urlToRequire = require('./urlToRequire')
module.exports = () => ({
postTransformNode: node => {
transform(node)
}
})
function transform (node) {
const tags = ['img', 'source']
if (tags.indexOf(node.tag) !== -1 && node.attrs) {
node.attrs.forEach(attr => {
if (attr.name === 'srcset') {
// same logic as in transform-require.js
const value = attr.value
const isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"'
if (!isStatic) {
return
}
// http://w3c.github.io/html/semantics-embedded-content.html#ref-for-image-candidate-string-5
const escapedSpaceCharacters = /( |\\t|\\n|\\f|\\r)+/g
const imageCandidates = value.substr(1, value.length - 2).split(',').map(s => {
// The attribute value arrives here with all whitespace, except normal spaces, represented by escape sequences
const [url, descriptor] = s.replace(escapedSpaceCharacters, ' ').trim().split(' ', 2)
return { require: urlToRequire(url), descriptor: descriptor }
})
// "require(url1)"
// "require(url1) 1x"
// "require(url1), require(url2)"
// "require(url1), require(url2) 2x"
// "require(url1) 1x, require(url2)"
// "require(url1) 1x, require(url2) 2x"
const code = imageCandidates.map(
({ require, descriptor }) => `${require} + "${descriptor ? ' ' + descriptor : ''}, " + `
).join('').slice(0, -6).concat('"').replace(/ \+ ""$/, '')
attr.value = code
}
})
}
}
module.exports = function urlToRequire (url) {
// same logic as in transform-require.js
const firstChar = url.charAt(0)
if (firstChar === '.' || firstChar === '~' || firstChar === '@') {
if (firstChar === '~') {
const secondChar = url.charAt(1)
url = url.slice(secondChar === '/' ? 2 : 1)
}
return `require("${url}")`
} else {
return `"${url}"`
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment