Blame view

node_modules/vue/src/compiler/to-function.js 2.77 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  /* @flow */
  
  import { noop, extend } from 'shared/util'
  import { warn as baseWarn, tip } from 'core/util/debug'
  
  type CompiledFunctionResult = {
    render: Function;
    staticRenderFns: Array<Function>;
  };
  
  function createFunction (code, errors) {
    try {
      return new Function(code)
    } catch (err) {
      errors.push({ err, code })
      return noop
    }
  }
  
  export function createCompileToFunctionFn (compile: Function): Function {
    const cache = Object.create(null)
  
    return function compileToFunctions (
      template: string,
      options?: CompilerOptions,
      vm?: Component
    ): CompiledFunctionResult {
      options = extend({}, options)
      const warn = options.warn || baseWarn
      delete options.warn
  
      /* istanbul ignore if */
      if (process.env.NODE_ENV !== 'production') {
        // detect possible CSP restriction
        try {
          new Function('return 1')
        } catch (e) {
          if (e.toString().match(/unsafe-eval|CSP/)) {
            warn(
              'It seems you are using the standalone build of Vue.js in an ' +
              'environment with Content Security Policy that prohibits unsafe-eval. ' +
              'The template compiler cannot work in this environment. Consider ' +
              'relaxing the policy to allow unsafe-eval or pre-compiling your ' +
              'templates into render functions.'
            )
          }
        }
      }
  
      // check cache
      const key = options.delimiters
        ? String(options.delimiters) + template
        : template
      if (cache[key]) {
        return cache[key]
      }
  
      // compile
      const compiled = compile(template, options)
  
      // check compilation errors/tips
      if (process.env.NODE_ENV !== 'production') {
        if (compiled.errors && compiled.errors.length) {
          warn(
            `Error compiling template:\n\n${template}\n\n` +
            compiled.errors.map(e => `- ${e}`).join('\n') + '\n',
            vm
          )
        }
        if (compiled.tips && compiled.tips.length) {
          compiled.tips.forEach(msg => tip(msg, vm))
        }
      }
  
      // turn code into functions
      const res = {}
      const fnGenErrors = []
      res.render = createFunction(compiled.render, fnGenErrors)
      res.staticRenderFns = compiled.staticRenderFns.map(code => {
        return createFunction(code, fnGenErrors)
      })
  
      // check function generation errors.
      // this should only happen if there is a bug in the compiler itself.
      // mostly for codegen development use
      /* istanbul ignore if */
      if (process.env.NODE_ENV !== 'production') {
        if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) {
          warn(
            `Failed to generate render function:\n\n` +
            fnGenErrors.map(({ err, code }) => `${err.toString()} in\n\n${code}\n`).join('\n'),
            vm
          )
        }
      }
  
      return (cache[key] = res)
    }
  }