const Component = instance.type as ComponentOptions
if (!instance.render) {
if (__RUNTIME_COMPILE__ && Component.template && !Component.render) {
- if (compile) {
- Component.render = compile(Component.template, {
- isCustomElement: instance.appContext.config.isCustomElement || NO,
- onError(err: CompilerError) {
- if (__DEV__) {
- const message = `Template compilation error: ${err.message}`
- const codeFrame =
- err.loc &&
- generateCodeFrame(
- Component.template!,
- err.loc.start.offset,
- err.loc.end.offset
- )
- warn(codeFrame ? `${message}\n${codeFrame}` : message)
- }
+ // __RUNTIME_COMPILE__ ensures `compile` is provided
+ Component.render = compile!(Component.template, {
+ isCustomElement: instance.appContext.config.isCustomElement || NO,
+ onError(err: CompilerError) {
+ if (__DEV__) {
+ const message = `Template compilation error: ${err.message}`
+ const codeFrame =
+ err.loc &&
+ generateCodeFrame(
+ Component.template!,
+ err.loc.start.offset,
+ err.loc.end.offset
+ )
+ warn(codeFrame ? `${message}\n${codeFrame}` : message)
}
- })
- } else if (__DEV__) {
+ }
+ })
+ }
+ if (__DEV__ && !Component.render) {
+ /* istanbul ignore if */
+ if (!__RUNTIME_COMPILE__ && Component.template) {
warn(
`Component provides template but the build of Vue you are running ` +
`does not support on-the-fly template compilation. Either use the ` +
`full build or pre-compile the template using Vue CLI.`
)
+ } else {
+ warn(
+ `Component is missing${
+ __RUNTIME_COMPILE__ ? ` template or` : ``
+ } render function.`
+ )
}
}
- if (__DEV__ && !Component.render) {
- warn(
- `Component is missing render function. Either provide a template or ` +
- `return a render function from setup().`
- )
- }
instance.render = (Component.render || NOOP) as RenderFunction
}
import { createApp } from '../src'
+import { mockWarn } from '@vue/runtime-test'
-it('should support on-the-fly template compilation', () => {
- const container = document.createElement('div')
- const App = {
- template: `{{ count }}`,
- data() {
- return {
- count: 0
+describe('compiler + runtime integration', () => {
+ mockWarn()
+
+ it('should support on-the-fly template compilation', () => {
+ const container = document.createElement('div')
+ const App = {
+ template: `{{ count }}`,
+ data() {
+ return {
+ count: 0
+ }
}
}
- }
- createApp().mount(App, container)
- expect(container.innerHTML).toBe(`0`)
-})
+ createApp().mount(App, container)
+ expect(container.innerHTML).toBe(`0`)
+ })
-it('should correctly normalize class with on-the-fly template compilation', () => {
- const container = document.createElement('div')
- const App = {
- template: `<div :class="{ test: demoValue, test2: !demoValue }"></div>`,
- data() {
- return {
- demoValue: true
- }
+ it('should warn template compilation errors with codeframe', () => {
+ const container = document.createElement('div')
+ const App = {
+ template: `<div v-if>`
}
- }
- createApp().mount(App, container)
- const classes = container.firstElementChild!.classList
- expect(classes.contains('test')).toBe(true)
- expect(classes.contains('test2')).toBe(false)
-})
+ createApp().mount(App, container)
+ expect(
+ `Template compilation error: End tag was not found`
+ ).toHaveBeenWarned()
+ expect(`v-if/v-else-if is missing expression`).toHaveBeenWarned()
+ expect(
+ `
+1 | <div v-if>
+ | ^^^^`.trim()
+ ).toHaveBeenWarned()
+ })
-it('should support custom element', () => {
- const app = createApp()
- const container = document.createElement('div')
- const App = {
- template: '<custom></custom>'
- }
- app.config.isCustomElement = tag => tag === 'custom'
- app.mount(App, container)
- expect(container.innerHTML).toBe('<custom></custom>')
+ it('should support custom element', () => {
+ const app = createApp()
+ const container = document.createElement('div')
+ const App = {
+ template: '<custom></custom>'
+ }
+ app.config.isCustomElement = tag => tag === 'custom'
+ app.mount(App, container)
+ expect(container.innerHTML).toBe('<custom></custom>')
+ })
})