Commit fb536909 authored by Evan You's avatar Evan You

refactor: wip use dependency compiler

parent 7c5b6acf
......@@ -218,6 +218,7 @@ The following option has been changed to resourceQuery:
- `compiler`
- `compilerOptions`
- `transpileOptions`
- `transformAssetUrls`
- `optimizeSSR`
- `hotReload`
const path = require('path')
const hash = require('hash-sum')
const parse = require('./parse')
const { parse } = require('vue-component-compiler')
const qs = require('querystring')
const plugin = require('./plugin')
const selectBlock = require('./select')
......
const qs = require('querystring')
const prettier = require('prettier')
const consolidate = require('consolidate')
const loaderUtils = require('loader-utils')
const compiler = require('vue-template-compiler')
const transpile = require('vue-template-es2015-compiler')
const transformAssetUrl = require('./modules/assetUrl')
const transformSrcset = require('./modules/srcset')
const { genTemplateHotReloadCode } = require('../hotReload')
const { compileTemplate } = require('vue-component-compiler')
// Loader that compiles raw template into JavaScript functions.
// This is injected by the global pitcher (../pitch) for template
// selection requests initiated from vue files.
// Also handles lang="xxx" pre-processing via consolidate if necessary.
module.exports = function (template) {
module.exports = function (source) {
const loaderContext = this
const query = qs.parse(this.resourceQuery.slice(1))
......@@ -20,69 +18,41 @@ module.exports = function (template) {
// vue-loader options because we've set an ident in the plugin and used that
// ident to create the request for this loader in the pitcher.
const options = loaderUtils.getOptions(loaderContext) || {}
const cb = loaderContext.async()
const compile = template => cb(null, actuallyCompile(
template,
options,
loaderContext,
query
))
if (query.lang && consolidate[query.lang]) {
preprocess(
template,
options,
loaderContext,
query.lang,
(err, template) => {
if (err) return cb(err)
compile(template)
}
)
} else {
compile(template)
}
}
function preprocess (rawTemplate, options, loaderContext, lang, cb) {
const engineOptions = Object.assign({
filename: loaderContext.resourcePath
}, options.template)
consolidate[lang].render(rawTemplate, engineOptions, (err, template) => {
if (err) {
return cb(err)
}
cb(null, template)
})
}
function actuallyCompile (sourceTemplate, options, loaderContext, query) {
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 hasFunctionalTemplate = query.functional
const isFunctional = query.functional
const userCompilerOptions = options.compilerOptions || {}
const compilerOptions = Object.assign({}, userCompilerOptions, {
scopeId: query.scoped ? `data-v-${id}` : null,
modules: defaultModules.concat(userCompilerOptions.modules || []),
comments: query.comments
})
// support user compiler
const compilerToUse = options.compiler || compiler
const preprocessOptions = Object.assign({
filename: this.resourcePath
}, options.template)
const compile =
isServer && compilerToUse.ssrCompile && options.optimizeSSR !== false
? compilerToUse.ssrCompile
: compilerToUse.compile
// for vue-component-compiler
const finalOptions = {
source,
// allow using custom compiler via options
compiler: options.compiler || compiler,
compilerOptions,
// handle possible lang="xxx"
preprocessLang: query.lang,
preprocessOptions,
// allow customizing behavior of vue-template-es2015-compiler
transpileOptions: options.transpileOptions,
isProduction,
isFunctional,
optimizeSSR: isServer && options.optimizeSSR !== false
}
const compiled = compile(sourceTemplate, compilerOptions)
const compiled = compileTemplate(finalOptions)
// tips
if (compiled.tips && compiled.tips.length) {
......@@ -91,65 +61,29 @@ function actuallyCompile (sourceTemplate, options, loaderContext, query) {
})
}
let code
// errors
if (compiled.errors && compiled.errors.length) {
loaderContext.emitError(
`\n Error compiling template:\n${pad(sourceTemplate)}\n` +
`\n Error compiling template:\n${pad(compiled.source)}\n` +
compiled.errors.map(e => ` - ${e}`).join('\n') +
'\n'
)
code =
`export var render = function () {}\n` +
`export var staticRenderFns = []`
} else {
const bubleOptions = options.buble || {
transforms: {
stripWithFunctional: hasFunctionalTemplate
}
}
const staticRenderFns = compiled.staticRenderFns.map(fn =>
toFunction(fn, hasFunctionalTemplate)
)
code =
transpile(
'var render = ' +
toFunction(compiled.render, hasFunctionalTemplate) +
'\n' +
'var staticRenderFns = [' +
staticRenderFns.join(',') +
']',
bubleOptions
) + '\n'
// prettify render fn
if (!isProduction) {
code = prettier.format(code, { semi: false })
}
// mark with stripped (this enables Vue to use correct runtime proxy detection)
if (!isProduction && bubleOptions.transforms.stripWith !== false) {
code += `render._withStripped = true\n`
}
code += `export { render, staticRenderFns }`
}
let { code } = compiled
// hot-reload
if (needsHotReload) {
code += genTemplateHotReloadCode(id)
}
// finish with ESM exports
code += `export { render, staticRenderFns }`
return code
}
function toFunction (code, hasFunctionalTemplate) {
return (
'function (' + (hasFunctionalTemplate ? '_h,_vm' : '') + ') {' + code + '}'
)
}
function pad (sourceTemplate) {
return sourceTemplate
function pad (source) {
return source
.split(/\r?\n/)
.map(line => ` ${line}`)
.join('\n')
......
const qs = require('querystring')
// transform the attrs on a SFC block descriptor into a resourceQuery string
exports.attrsToQuery = (attrs, langFallback) => {
let query = ``
for (const name in attrs) {
......
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