From 1f1229dd11b0b4ae9856abb8624c66514445f07a Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Tue, 27 Aug 2019 17:20:10 +0800 Subject: [PATCH] fix(cli): output resource path for compiler errors #604 --- .../__tests__/compiler-extra.spec.js | 7 +- .../uni-template-compiler/__tests__/demo.js | 2 +- packages/uni-template-compiler/lib/index.js | 16 +- .../lib/script/traverse/data/event.js | 216 +++++++++--------- 4 files changed, 130 insertions(+), 111 deletions(-) diff --git a/packages/uni-template-compiler/__tests__/compiler-extra.spec.js b/packages/uni-template-compiler/__tests__/compiler-extra.spec.js index 71c08eb11..7238037e8 100644 --- a/packages/uni-template-compiler/__tests__/compiler-extra.spec.js +++ b/packages/uni-template-compiler/__tests__/compiler-extra.spec.js @@ -584,7 +584,12 @@ describe('mp:compiler-extra', () => { `` ) }) - it('generate event ', () => { + it('generate event ', () => { + assertCodegen( + ``, + `` + ) + assertCodegen( `{{item.title}}`, `{{item.title}}` diff --git a/packages/uni-template-compiler/__tests__/demo.js b/packages/uni-template-compiler/__tests__/demo.js index cfca7bbdc..7ead89107 100644 --- a/packages/uni-template-compiler/__tests__/demo.js +++ b/packages/uni-template-compiler/__tests__/demo.js @@ -2,7 +2,7 @@ const compiler = require('../lib') const res = compiler.compile( ` - + `, { resourcePath: '/User/fxy/Documents/test.wxml', mp: { diff --git a/packages/uni-template-compiler/lib/index.js b/packages/uni-template-compiler/lib/index.js index 9e6b3cd5e..084a21972 100644 --- a/packages/uni-template-compiler/lib/index.js +++ b/packages/uni-template-compiler/lib/index.js @@ -55,10 +55,18 @@ module.exports = { } // console.log(`function render(){${res.render}}`) const ast = parser.parse(`function render(){${res.render}}`) - - res.render = generateScript(traverseScript(ast, state), state) - - let template = generateTemplate(traverseTemplate(ast, state), state) + let template = '' + + try { + res.render = generateScript(traverseScript(ast, state), state) + template = generateTemplate(traverseTemplate(ast, state), state) + } catch (e) { + console.error(e) + throw new Error('Compile failed at ' + options.resourcePath.replace( + path.extname(options.resourcePath), + '.vue' + )) + } res.specialMethods = state.options.specialMethods || new Set() delete state.options.specialMethods diff --git a/packages/uni-template-compiler/lib/script/traverse/data/event.js b/packages/uni-template-compiler/lib/script/traverse/data/event.js index 22ec016c5..8efef87e7 100644 --- a/packages/uni-template-compiler/lib/script/traverse/data/event.js +++ b/packages/uni-template-compiler/lib/script/traverse/data/event.js @@ -167,7 +167,7 @@ function getMethodName (methodName) { return methodName === '__HOLDER__' ? '' : methodName } -function parseEventByCallExpression (callExpr, methods) { +function parseEventByCallExpression (callExpr, methods) { let methodName = callExpr.callee.name if (methodName === '$set') { methodName = INTERNAL_SET_SYNC @@ -197,12 +197,12 @@ function parseEventByCallExpression (callExpr, methods) { arrayExpression.push(t.arrayExpression(argsExpression)) } } - methods.push(t.arrayExpression(arrayExpression)) + methods.push(t.arrayExpression(arrayExpression)) } function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, tagName, ret) { const key = keyPath.node - let type = key.value || key.name + let type = key.value || key.name || '' const isCustom = isComponent && !isNativeOn @@ -211,124 +211,126 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, let isPassive = false let isOnce = false - isPassive = type.charAt(0) === VUE_EVENT_MODIFIERS.passive - type = isPassive ? type.slice(1) : type + let methods = [] - isOnce = type.charAt(0) === VUE_EVENT_MODIFIERS.once // Prefixed last, checked first - type = isOnce ? type.slice(1) : type + if (type) { + isPassive = type.charAt(0) === VUE_EVENT_MODIFIERS.passive + type = isPassive ? type.slice(1) : type - isCapture = type.charAt(0) === VUE_EVENT_MODIFIERS.capture - type = isCapture ? type.slice(1) : type + isOnce = type.charAt(0) === VUE_EVENT_MODIFIERS.once // Prefixed last, checked first + type = isOnce ? type.slice(1) : type - const specialEvents = state.options.platform.specialEvents - const isSpecialEvent = specialEvents[tagName] && Object.keys(specialEvents[tagName]).includes(type) + isCapture = type.charAt(0) === VUE_EVENT_MODIFIERS.capture + type = isCapture ? type.slice(1) : type - let methods = [] + const specialEvents = state.options.platform.specialEvents + const isSpecialEvent = specialEvents[tagName] && Object.keys(specialEvents[tagName]).includes(type) - if (!valuePath.isArrayExpression()) { - valuePath = [valuePath] - } else { - valuePath = valuePath.get('elements') - } + if (!valuePath.isArrayExpression()) { + valuePath = [valuePath] + } else { + valuePath = valuePath.get('elements') + } - valuePath.forEach(funcPath => { - if ( // wxs event - funcPath.isMemberExpression() && - t.isIdentifier(funcPath.node.object) && - state.options.filterModules.includes(funcPath.node.object.name) - ) { - const { - getEventType, - formatEventType - } = state.options.platform - const wxsEventType = formatEventType(getEventType(type)) - if (key.value) { - key.value = wxsEventType - } else { - key.name = wxsEventType - } - } else if (funcPath.isIdentifier()) { // on:{click:handle} - if (!isSpecialEvent) { - const arrayExpression = [t.stringLiteral(getMethodName(funcPath.node.name))] - if (!isCustom) { // native events - arrayExpression.push(defaultArgs) + valuePath.forEach(funcPath => { + if ( // wxs event + funcPath.isMemberExpression() && + t.isIdentifier(funcPath.node.object) && + state.options.filterModules.includes(funcPath.node.object.name) + ) { + const { + getEventType, + formatEventType + } = state.options.platform + const wxsEventType = formatEventType(getEventType(type)) + if (key.value) { + key.value = wxsEventType + } else { + key.name = wxsEventType } - methods.push(t.arrayExpression(arrayExpression)) - } else { - if (!state.options.specialMethods) { - state.options.specialMethods = new Set() + } else if (funcPath.isIdentifier()) { // on:{click:handle} + if (!isSpecialEvent) { + const arrayExpression = [t.stringLiteral(getMethodName(funcPath.node.name))] + if (!isCustom) { // native events + arrayExpression.push(defaultArgs) + } + methods.push(t.arrayExpression(arrayExpression)) + } else { + if (!state.options.specialMethods) { + state.options.specialMethods = new Set() + } + state.options.specialMethods.add(funcPath.node.name) } - state.options.specialMethods.add(funcPath.node.name) - } - } else if (isSpecialEvent) { - state.errors.add( - `${tagName} 组件 ${type} 事件仅支持 @${type}="methodName" 方式绑定` - ) - } else if (funcPath.isArrowFunctionExpression()) { // e=>count++ - methods.push(addEventExpressionStatement(funcPath, state, isCustom)) - } else { - let anonymous = true + } else if (isSpecialEvent) { + state.errors.add( + `${tagName} 组件 ${type} 事件仅支持 @${type}="methodName" 方式绑定` + ) + } else if (funcPath.isArrowFunctionExpression()) { // e=>count++ + methods.push(addEventExpressionStatement(funcPath, state, isCustom)) + } else { + let anonymous = true - // "click":function($event) {click1(item);click2(item);} - const body = funcPath.node.body.body - if (body.length) { - const exprStatements = body.filter(node => { - return t.isExpressionStatement(node) && t.isCallExpression(node.expression) - }) - if (exprStatements.length === body.length) { - anonymous = false - exprStatements.forEach(exprStatement => { - parseEventByCallExpression(exprStatement.expression, methods) + // "click":function($event) {click1(item);click2(item);} + const body = funcPath.node.body.body + if (body.length) { + const exprStatements = body.filter(node => { + return t.isExpressionStatement(node) && t.isCallExpression(node.expression) }) - } - } - - anonymous && funcPath.traverse({ - noScope: true, - MemberExpression (path) { - if (path.node.object.name === '$event' && path.node.property.name === - 'stopPropagation') { - isCatch = true - path.stop() - } - }, - AssignmentExpression (path) { // "update:title": function($event) {title = $event} - const left = path.node.left - const right = path.node.right - // v-bind:title.sync="title" - if (t.isIdentifier(left) && - t.isIdentifier(right) && - right.name === '$event' && - type.indexOf('update:') === 0) { - methods.push(t.arrayExpression( // ['$set',['title','$event']] - [ - t.stringLiteral(INTERNAL_SET_SYNC), - t.arrayExpression([ - t.identifier(left.name), - t.stringLiteral(left.name), - t.stringLiteral('$event') - ]) - ] - )) + if (exprStatements.length === body.length) { anonymous = false - path.stop() + exprStatements.forEach(exprStatement => { + parseEventByCallExpression(exprStatement.expression, methods) + }) } - }, - ReturnStatement (path) { - const argument = path.node.argument - if (t.isCallExpression(argument)) { - if (t.isIdentifier(argument.callee)) { + } + + anonymous && funcPath.traverse({ + noScope: true, + MemberExpression (path) { + if (path.node.object.name === '$event' && path.node.property.name === + 'stopPropagation') { + isCatch = true + path.stop() + } + }, + AssignmentExpression (path) { // "update:title": function($event) {title = $event} + const left = path.node.left + const right = path.node.right + // v-bind:title.sync="title" + if (t.isIdentifier(left) && + t.isIdentifier(right) && + right.name === '$event' && + type.indexOf('update:') === 0) { + methods.push(t.arrayExpression( // ['$set',['title','$event']] + [ + t.stringLiteral(INTERNAL_SET_SYNC), + t.arrayExpression([ + t.identifier(left.name), + t.stringLiteral(left.name), + t.stringLiteral('$event') + ]) + ] + )) anonymous = false - parseEventByCallExpression(argument, methods) + path.stop() + } + }, + ReturnStatement (path) { + const argument = path.node.argument + if (t.isCallExpression(argument)) { + if (t.isIdentifier(argument.callee)) { + anonymous = false + parseEventByCallExpression(argument, methods) + } } } + }) + if (anonymous) { + methods.push(addEventExpressionStatement(funcPath, state, isComponent, isNativeOn)) } - }) - if (anonymous) { - methods.push(addEventExpressionStatement(funcPath, state, isComponent, isNativeOn)) } - } - }) + }) + } return { type, @@ -345,6 +347,10 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, function _processEvent (path, state, isComponent, isNativeOn = false, tagName, ret) { const opts = [] + // remove invalid event + path.node.value.properties = path.node.value.properties.filter(property => { + return property.key.value || property.key.name + }) const len = path.node.value.properties.length for (let i = 0; i < len; i++) { const propertyPath = path.get(`value.properties.${i}`) @@ -439,4 +445,4 @@ module.exports = function processEvent (paths, path, state, isComponent, tagName ) return ret -} +} -- GitLab