Project details:  A  Todo  application with  / app  `(main page) and  / login  (login page) two routes 
 when rendering  ssr , I used  routing lazy loading , and then  packaged the front-end code with webpack, I packaged  successfully, and then there was an error accessing the main page when starting the server port (but  there is no problem with the generation environment , production environment debugging uses webpack-dev-server + koa to start two ports). The reason for the error in production environment access is: 
TypeError: Cannot read property "call" of undefined
    at r (webpack/bootstrap:39:0)
    at Object.<anonymous> (client/views/todo/todo.vue?6149:6:0)
    at r (webpack/bootstrap:39:0)
    at Object.<anonymous> (client/views/todo/todo.vue?7847:6:0)
    at r (webpack/bootstrap:39:0)
    at VueComponent.s (client/views/todo/todo.vue:11:0)
    at VueComponent.c (node_modules/vue-loader/lib/runtime/component-normalizer.js:65:0)
    at callHook (D:\Editors\WebStorm\Files\20180423-imooc-vue-todo-further\node_modules\vue\dist\vue.runtime.common.js:2919:21)
    at VueComponent.Vue._init (D:\Editors\WebStorm\Files\20180423-imooc-vue-todo-further\node_modules\vue\dist\vue.runtime.common.js:4624:5)
    at new VueComponent (D:\Editors\WebStorm\Files\20180423-imooc-vue-todo-further\node_modules\vue\dist\vue.runtime.common.js:4796:12)
 I Baidu a lot of answers, but are invalid, I  suspect is component lazy loading error , because  Login component  lazy loading no problem, and  Todo component  load is wrong, the difference between them is that Login component  does not have sub-components , and Todo also has  sub-components . 
I am puzzled. I hope the bosses will answer.
< H2 > part of the code < / H2 > < hr > the following is the configuration of  webpack packaging : 
  webpack basic configuration baseConfig:  
const baseConfig = {
  mode: process.env.NODE_ENV || "production", // webpack 4 
  target: "web",
  entry: {
    app: path.join(__dirname, "../client/client-entry.js")
  },
  output: {
    path: path.join(__dirname, "../public"),
    filename: "bundle.[hash:8].js",
    // devServerhistoryApiFallback
    publicPath: "http://127.0.0.1:8080/public/"
  },
  module: {
    rules: [
      {
        test: /\.(vue|jsx|js)$/,
        loader: "eslint-loader",
        exclude: /node_modules/,
        enforce: "pre" /* loaderloader */
      },
      {
        test: /\.vue$/,
        loader: "vue-loader",
        options: createVueLoaderOptions(isDev)
      },
      {
        test: /\.jsx$/,
        loader: "babel-loader"
      },
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: "/node_modules/"
      },
      {
        test: /\.(jpg|jpeg|png|svg|gif)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 1024,
              name: "resources/[path][name].[hash:8].[ext]"
            }
          }
        ]
      }
    ]
  }
}  configuration in the build environment:  
 // 
  config = merge(baseConfig, {
    mode: "production",
    entry: {
      app: path.join(__dirname, "../client/client-entry.js")
    },
    output: {
      filename: "[name].[chunkhash:8].js",
      publicPath: "/public/"
    },
    module: {
      rules: [
        {
          test: /\.styl$/,
          use: ExtractPlugin.extract({
            /* style-loaderjshtml */
            fallback: "style-loader",
            use: [
              "css-loader",
              {
                loader: "postcss-loader",
                options: {
                  sourceMap: true
                }
              },
              "stylus-loader"
            ]
          })
        }
      ]
    },
    plugins: defaultPlugins.concat(new ExtractPlugin("styles.[chunkhash].css")),
    optimization: {
      splitChunks: {
        chunks: "all"
      },
      runtimeChunk: true
    }
  })
the following is part of the code for routing lazy loading:
// /login/app
const Todo = () => import("../views/todo/todo.vue")
const Login = () => import("../views/login/login.vue")
// xxx
export default [
  {
    path: "/",
    redirect: "/app"
  },
  {
    path: "/app",
    component: Todo,
    name: "app",
  },
  {
    path: "/login",
    component: Login
  }
]if routing lazy loading is not used, after webpack is packaged, there will be no problem with production environment access.
// 
import Todo from "../views/todo/todo.vue"
import Login from "../views/login/login.vue"
// xxx
export default [
  {
    path: "/",
    redirect: "/app"
  },
  {
    path: "/app",
    component: Todo,
    name: "app",
  },
  {
    path: "/login",
    component: Login
  }
] paste the code of  login.vue  and  todo.vue  components separately: 
  login.vue:  
<template>
  <div>
    
  </div>
</template>
<script>
  export default {
    metaInfo: {
      title: "Login - Todo App"
    }
  }
</script>  todo.vue:  
<template>
  <section id="todo-wrapper" class="todo-wrapper">
    <input
      type="text"
      class="add-input"
      @keyup.enter="addTodo"
      autofocus="autofocus"
      placeholder=""
    >
    <Item
      v-for="todo in filterTodos"
      :todo="todo"
      :key="todo.id"
      @del="deleteTodo"
    ></Item>
    <Tabs :todos="todos"
          :filter="filter"
          @changeFilter="changeFilter"
          @clearCompleted="clearCompleted"></Tabs>
  </section>
</template>
<script>
  import Item from "./item.vue"
  import Tabs from "./tabs.vue"
  
  let id = 0
  
  export default {
    metaInfo: {
      title: "The Todo App"
    },
    components: {
      Item,
      Tabs
    },
    props: ["id"],
    data () {
      return {
        filter: "all",
        todos: []
      }
    },
    mounted () {
      console.log(this.$route)
      console.log("id: ", this.id)
    },
    computed: {
      filterTodos () {
        let state = this.filter
        if (state === "all") {
          return this.todos
        } else if (state === "active") {
          return this.todos.filter(todo => !todo.completed)
        } else {
          return this.todos.filter(todo => todo.completed)
        }
      }
    },
    methods: {
      addTodo (e) {
        this.todos.unshift({
          id: idPP,
          content: e.target.value.trim(),
          completed: false
        })
        e.target.value = ""
      },
      deleteTodo (id) {
        this.todos.splice(this.todos.findIndex(todo => todo.id === id), 1)
      },
      clearCompleted () {
        this.todos = this.todos.filter(todo => !todo.completed)
      },
      changeFilter (state) {
        this.filter = state
      }
    }
  }
</script>
<style lang="stylus" scoped>
  .todo-wrapper {
    width 600px
    margin 0 auto
    padding 10px
    box-shadow 0 0 5px -sharp666
    background-color -sharpfff
  }
  
  .add-input {
    position relative
    width 100%
    padding 16px
    outline none
    border none
    font-size 24px
    line-height 40px
    box-shadow inset 0 -2px 1px rgba(0, 0, 0, 0.03)
  }
</style>
Thank you.
