Parcourir la source

detect and warn against using keywords as property names

Evan You il y a 10 ans
Parent
commit
02d5330e50
2 fichiers modifiés avec 25 ajouts et 5 suppressions
  1. 23 4
      src/compiler/error-detector.js
  2. 2 1
      test/unit/features/options/template.spec.js

+ 23 - 4
src/compiler/error-detector.js

@@ -2,6 +2,12 @@
 
 import { dirRE } from './parser/index'
 
+const keywordRE = new RegExp('\\b' + (
+  'do,if,in,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
+  'super,throw,while,yield,delete,export,import,return,switch,typeof,default,' +
+  'extends,finally,continue,debugger,function,arguments,instanceof'
+).split(',').join('\\b|\\b') + '\\b')
+
 // detect problematic expressions in a template
 export function detectErrors (ast: ?ASTNode): Array<string> {
   const errors: Array<string> = []
@@ -32,9 +38,22 @@ function checkNode (node: ASTNode, errors: Array<string>) {
 }
 
 function checkExpression (exp: string, text: string, errors: Array<string>) {
-  try {
-    new Function(exp)
-  } catch (e) {
-    errors.push(`- invalid expression: ${text}`)
+  exp = stripToString(exp)
+  const keywordMatch = exp.match(keywordRE)
+  if (keywordMatch) {
+    errors.push(
+      `- avoid using JavaScript keyword as property name: ` +
+      `"${keywordMatch[0]}" in expression ${text}`
+    )
+  } else {
+    try {
+      new Function(exp)
+    } catch (e) {
+      errors.push(`- invalid expression: ${text}`)
+    }
   }
 }
+
+function stripToString (exp) {
+  return exp.replace(/^_s\((.*)\)$/, '$1')
+}

+ 2 - 1
test/unit/features/options/template.spec.js

@@ -53,10 +53,11 @@ describe('Options template', () => {
 
   it('warn error in generated function', () => {
     new Vue({
-      template: '<div v-if="!@">{{ a"" }}</div>'
+      template: '<div v-if="!@"><span>{{ a"" }}</span><span>{{ do + 1 }}</span></div>'
     }).$mount()
     expect('failed to compile template').toHaveBeenWarned()
     expect('invalid expression: v-if="!@"').toHaveBeenWarned()
     expect('invalid expression: {{ a"" }}').toHaveBeenWarned()
+    expect('avoid using JavaScript keyword as property name: "do" in expression {{ do + 1 }}').toHaveBeenWarned()
   })
 })