Search code examples
vue.jswebsocketreal-timevuejs3pusher

Configuring Pusher on Vue3


I have a project in Vue3 and want to implement a real time API or a web socket. So I attempted to use pusher using Vue third part libraries which are pusher-vue and vue-pusher. Using pusher-vue I am getting the error: Uncaught TypeError: e.prototype is undefined. Using vue-pusher I am getting the error: Uncaught TypeError: Vue.prototype is undefined. The following are the libraries' configurations:

PUSHER VUE

Component.vue

export default{
  channels: {
       applications_channel: {
           subscribeOnMount: true,
           subscribed(){
               console.log("Some text")
           },

           bind:{
               add_application_event(data){
                   console.log(data)
               }
           }
       }
  }
}

main.js

createApp(App)
.use(PusherVue, {
    app_key: "MY_KEY",
    cluster: 'MY_CLUSTER',
    debug: true,
    debugLevel: "all"
})
.mount("#app")

VUE PUSHER

Component.vue

export default{
  read(){
      var channel = this.$pusher.subscribe('applications-channel')

            channel.bind('add-application-event', ({ log }) => {
                console.log(log);
            })
       }
}

main.js

createApp(App)
.use(require("vue-pusher"), {
    api_key: "MY_KEY",
    options: {
        cluster: 'MY_CLUSTER',
        ecrypted: true,
    }
})
.mount("#app")

May you please help with how can I configure this on Vue3 or recommend any beginner friendly alternatives to achieve the same functionality on Vue3.


Solution

  • Both pusher-vue and vue-pusher were built for Vue 2, so you need to use the Vue 3 migration build to make the library work in your project.

    To setup your Vue CLI scaffolded project:

    1. Install the Vue compatibility build and SFC compiler that matches your Vue build version (i.e., install @vue/compat@^3.1.0 and @vue/compiler-sfc@^3.1.0 if you have vue@^3.1.0 in package.json):

      npm i -S @vue/compat@^3.1.0
      npm i -S @vue/compiler-sfc@^3.1.0
      
    2. Configure Webpack to alias vue to the @vue/compat build, and set vue-loader's compatibility mode to Vue 2:

      // vue.config.js
      module.exports = {
        chainWebpack: config => {
          config.resolve.alias.set('vue', '@vue/compat')
      
          config.module
            .rule('vue')
            .use('vue-loader')
            .tap(options => {
              return {
                ...options,
                compilerOptions: {
                  compatConfig: {
                    MODE: 2
                  }
                }
              }
            })
        }
      }
      

    demo: vue-pusher in Vue 3 w/migration build

    However, vue-pusher 1.1.0 seems to only expose a new instance of Pusher (from pusher-js) as this.$pusher on the Vue instance. That code could easily be migrated to Vue 3 as a plugin:

    // plugins/pusher.js
    export default (app, { apiKey, ...options }) => {
      const Pusher = require('pusher-js')
      app.config.globalProperties.$pusher = new Pusher(apiKey, options)
    }
    
    // main.js
    const { createApp } = require('vue')
    import App from './App.vue'
    import PusherPlugin from './plugins/pusher'
    
    createApp(App)
      .use(PusherPlugin, { apiKey: 'YOUR_API_KEY', cluster: 'YOUR_CLUSTER' })
      .mount('#app')
    

    demo: pusher-js in Vue 3