Access routing error after Webpack4+vue+ssr packaging

Project details: A Todo application with / app `(main page) and / login (login page) two routes

< hr > < H2 > error details < / H2 >

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)
< H2 > preliminary inference of the cause of error < / H2 >

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
    }
  })
< hr >

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
  }
]
< hr >

paste the code of login.vue and todo.vue components separately:

< hr >

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.

Mar.10,2021

Hello, I have encountered a similar problem. If I do not use routing lazy loading, after webpack is packaged, there will be no problem with access to the production environment. Have you solved this?


ask whether it has been solved now. I have also encountered this problem

.
Menu