|
1 | 1 | /* @flow */
|
2 | 2 |
|
3 | 3 | import { isUnaryTag } from './util'
|
4 |
| -import { warn, tip } from 'core/util/debug' |
5 |
| -import { detectErrors } from 'compiler/error-detector' |
6 |
| -import { compile as baseCompile } from 'compiler/index' |
7 |
| -import { extend, genStaticKeys, noop } from 'shared/util' |
8 |
| -import { isReservedTag, mustUseProp, getTagNamespace, isPreTag } from '../util/index' |
| 4 | +import { genStaticKeys } from 'shared/util' |
| 5 | +import { createCompiler } from 'compiler/index' |
9 | 6 |
|
10 | 7 | import modules from './modules/index'
|
11 | 8 | import directives from './directives/index'
|
12 | 9 |
|
13 |
| -const cache: { [key: string]: CompiledFunctionResult } = Object.create(null) |
| 10 | +import { |
| 11 | + isPreTag, |
| 12 | + mustUseProp, |
| 13 | + isReservedTag, |
| 14 | + getTagNamespace |
| 15 | +} from '../util/index' |
14 | 16 |
|
15 | 17 | export const baseOptions: CompilerOptions = {
|
16 | 18 | expectHTML: true,
|
17 | 19 | modules,
|
18 |
| - staticKeys: genStaticKeys(modules), |
19 | 20 | directives,
|
20 |
| - isReservedTag, |
| 21 | + isPreTag, |
21 | 22 | isUnaryTag,
|
22 | 23 | mustUseProp,
|
| 24 | + isReservedTag, |
23 | 25 | getTagNamespace,
|
24 |
| - isPreTag |
25 |
| -} |
26 |
| - |
27 |
| -export function compile ( |
28 |
| - template: string, |
29 |
| - options?: CompilerOptions |
30 |
| -): CompiledResult { |
31 |
| - const finalOptions = Object.create(baseOptions) |
32 |
| - const errors = [] |
33 |
| - const tips = [] |
34 |
| - finalOptions.warn = (msg, tip) => { |
35 |
| - (tip ? tips : errors).push(msg) |
36 |
| - } |
37 |
| - |
38 |
| - if (options) { |
39 |
| - // merge custom modules |
40 |
| - if (options.modules) { |
41 |
| - finalOptions.modules = (baseOptions.modules || []).concat(options.modules) |
42 |
| - } |
43 |
| - // merge custom directives |
44 |
| - if (options.directives) { |
45 |
| - finalOptions.directives = extend( |
46 |
| - Object.create(baseOptions.directives), |
47 |
| - options.directives |
48 |
| - ) |
49 |
| - } |
50 |
| - // copy other options |
51 |
| - for (const key in options) { |
52 |
| - if (key !== 'modules' && key !== 'directives') { |
53 |
| - finalOptions[key] = options[key] |
54 |
| - } |
55 |
| - } |
56 |
| - } |
57 |
| - |
58 |
| - const compiled = baseCompile(template, finalOptions) |
59 |
| - if (process.env.NODE_ENV !== 'production') { |
60 |
| - errors.push.apply(errors, detectErrors(compiled.ast)) |
61 |
| - } |
62 |
| - compiled.errors = errors |
63 |
| - compiled.tips = tips |
64 |
| - return compiled |
65 |
| -} |
66 |
| - |
67 |
| -export function compileToFunctions ( |
68 |
| - template: string, |
69 |
| - options?: CompilerOptions, |
70 |
| - vm?: Component |
71 |
| -): CompiledFunctionResult { |
72 |
| - options = extend({}, options) |
73 |
| - |
74 |
| - /* istanbul ignore if */ |
75 |
| - if (process.env.NODE_ENV !== 'production') { |
76 |
| - // detect possible CSP restriction |
77 |
| - try { |
78 |
| - new Function('return 1') |
79 |
| - } catch (e) { |
80 |
| - if (e.toString().match(/unsafe-eval|CSP/)) { |
81 |
| - warn( |
82 |
| - 'It seems you are using the standalone build of Vue.js in an ' + |
83 |
| - 'environment with Content Security Policy that prohibits unsafe-eval. ' + |
84 |
| - 'The template compiler cannot work in this environment. Consider ' + |
85 |
| - 'relaxing the policy to allow unsafe-eval or pre-compiling your ' + |
86 |
| - 'templates into render functions.' |
87 |
| - ) |
88 |
| - } |
89 |
| - } |
90 |
| - } |
91 |
| - |
92 |
| - // check cache |
93 |
| - const key = options.delimiters |
94 |
| - ? String(options.delimiters) + template |
95 |
| - : template |
96 |
| - if (cache[key]) { |
97 |
| - return cache[key] |
98 |
| - } |
99 |
| - |
100 |
| - // compile |
101 |
| - const compiled = compile(template, options) |
102 |
| - |
103 |
| - // check compilation errors/tips |
104 |
| - if (process.env.NODE_ENV !== 'production') { |
105 |
| - if (compiled.errors && compiled.errors.length) { |
106 |
| - warn( |
107 |
| - `Error compiling template:\n\n${template}\n\n` + |
108 |
| - compiled.errors.map(e => `- ${e}`).join('\n') + '\n', |
109 |
| - vm |
110 |
| - ) |
111 |
| - } |
112 |
| - if (compiled.tips && compiled.tips.length) { |
113 |
| - compiled.tips.forEach(msg => tip(msg, vm)) |
114 |
| - } |
115 |
| - } |
116 |
| - |
117 |
| - // turn code into functions |
118 |
| - const res = {} |
119 |
| - const fnGenErrors = [] |
120 |
| - res.render = makeFunction(compiled.render, fnGenErrors) |
121 |
| - const l = compiled.staticRenderFns.length |
122 |
| - res.staticRenderFns = new Array(l) |
123 |
| - for (let i = 0; i < l; i++) { |
124 |
| - res.staticRenderFns[i] = makeFunction(compiled.staticRenderFns[i], fnGenErrors) |
125 |
| - } |
126 |
| - |
127 |
| - // check function generation errors. |
128 |
| - // this should only happen if there is a bug in the compiler itself. |
129 |
| - // mostly for codegen development use |
130 |
| - /* istanbul ignore if */ |
131 |
| - if (process.env.NODE_ENV !== 'production') { |
132 |
| - if ((!compiled.errors || !compiled.errors.length) && fnGenErrors.length) { |
133 |
| - warn( |
134 |
| - `Failed to generate render function:\n\n` + |
135 |
| - fnGenErrors.map(({ err, code }) => `${err.toString()} in\n\n${code}\n`).join('\n'), |
136 |
| - vm |
137 |
| - ) |
138 |
| - } |
139 |
| - } |
140 |
| - |
141 |
| - return (cache[key] = res) |
| 26 | + staticKeys: genStaticKeys(modules) |
142 | 27 | }
|
143 | 28 |
|
144 |
| -function makeFunction (code, errors) { |
145 |
| - try { |
146 |
| - return new Function(code) |
147 |
| - } catch (err) { |
148 |
| - errors.push({ err, code }) |
149 |
| - return noop |
150 |
| - } |
151 |
| -} |
| 29 | +const { compile, compileToFunctions } = createCompiler(baseOptions) |
| 30 | +export { compile, compileToFunctions } |
0 commit comments