Repository: vuejs/vue
Pull request: fix inline-template crashing (fix #9361)

<!-- PULL REQUEST TEMPLATE -->
<!-- (Update "[ ]" to "[x]" to check a box) -->

**What kind of change does this PR introduce?** (check at least one)

- [x] Bugfix
- [ ] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Build-related changes
- [ ] Other, please describe:

**Does this PR introduce a breaking change?** (check one)

- [ ] Yes
- [x] No

If yes, please describe the impact and migration path for existing applications:

**The PR fulfills these requirements:**

- [x] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
- [x] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [x] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [x] New/updated tests are included

If adding a **new feature**, the PR's description includes:
- [ ] A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

**Other information:**
The generator function for inline templates `genInlineTemplate ` did not prevent the generation of code when an invalid template was being introduced. 

The solution introduced is verifying the existence of the first child before checking for its type, this should prevent the application from crashing trying to access attributes in an `undefined` child variable.

closes #9361

### How to Reproduce

<details>
<summary>Index HTML</summary>

```HTML
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Hello World!</title>
    <!-- This is a development version of Vue.js! -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
    <script src="./vue.js"></script>
    <script src="/main.js" type="module"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

```

</details>

<details><summary>JS code</summary>

```JavaScript
// ### main.js ###
import App from "./App.js";

Vue.config.productionTip = false;

new Vue({
  render: h => h(App),
}).$mount(`#app`);


// ### App.js ###
var HelloWorld = {
  name: 'HelloWorld',
  template: `<div></div>`,
  props: {
    msg: String
  }
}

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  template: `
    <div id="app">
      <div is="helloWorld" inline-template></div>
    </div>
  `,
};

```

</details>

<details><summary>Error with current implementation</summary>

![image](https://user-images.githubusercontent.com/4977614/51681442-b8c12a80-1fcb-11e9-9b05-ff1d464df307.png)

</details>

<details><summary>Error with this fix</summary>

![image](https://user-images.githubusercontent.com/4977614/51681469-d1c9db80-1fcb-11e9-88db-1577caa2c6d1.png)

</details>

Changed files:
filename: src/compiler/codegen/index.js
patch: @@ -346,7 +346,7 @@ function genInlineTemplate (el: ASTElement, state: CodegenState): ?string {
       { start: el.start }
     )
   }
-  if (ast.type === 1) {
+  if (ast && ast.type === 1) {
     const inlineRenderFns = generate(ast, state.options)
     return `inlineTemplate:{render:function(){${
       inlineRenderFns.render

filename: test/unit/modules/compiler/codegen.spec.js
patch: @@ -591,14 +591,21 @@ describe('codegen', () => {
       '<my-component inline-template><hr><hr></my-component>',
       `with(this){return _c('my-component',{inlineTemplate:{render:function(){with(this){return _c('hr')}},staticRenderFns:[]}})}`
     )
-    try {
-      assertCodegen(
-        '<my-component inline-template></my-component>',
-        ''
-      )
-    } catch (e) {}
+    assertCodegen(
+      '<my-component inline-template></my-component>',
+      `with(this){return _c('my-component',{})}`
+    )
+    // have "is" attribute
+    assertCodegen(
+      '<div is="myComponent" inline-template><div></div></div>',
+      `with(this){return _c("myComponent",{tag:"div",inlineTemplate:{render:function(){with(this){return _c('div')}},staticRenderFns:[]}})}`
+    )
+    assertCodegen(
+      '<div is="myComponent" inline-template></div>',
+      `with(this){return _c("myComponent",{tag:"div"})}`
+    )
     expect('Inline-template components must have exactly one child element.').toHaveBeenWarned()
-    expect(console.error.calls.count()).toBe(2)
+    expect(console.error.calls.count()).toBe(3)
   })
 
   it('generate static trees inside v-for', () => {