Sharing component logic between Vue apps
Tags: vue, vuecli, javascript, pwa
Published: 2019-04-29 15:46:28

---
title: Sharing component logic between Vue apps
published: true
description: 
tags: #vue #vue-cli #javascript #pwa
cover_image: https://thepracticaldev.s3.amazonaws.com/i/cc4ocporm4j7g6vu2cdy.jpeg
---

Let's say there is a need to have 2 separate Vue apps, which need to have some shared logic. One of those cases would be having mobile (pwa) app and web app sharing some logic like authentication or other component-based logic, but having different functionality for same kind of modules (effectively meaning having their own components).

This might not be your wanted workflow, usually you would just scaffold a vue pwa app, and use responsive design to provide same app to both mobile and web (which is much easier, maintenance wise), but if you do have similar requirements for your project like I did, continue with reading.

There is at least 2 ways to approach this, but I wanna discuss one-project setup, where vue cli is configured to provide separate builds for separate projects, and still having a lot of logic shared.

Your src folder tree should look like this: 

```
|--src
    |--mob
        |--components
        |--views
        |--router
        |--main.js
        |--App.vue
    |--web
        |--components
        |--views
        |--router
        |--main.js
        |--App.vue
    |--assets
    |--store
    |--shared
```

Considering we want different builds, it means that we have to provide separate entrypoints (main.js and App.vue files), components, and also separate routers since views components are top-level router components (in case your app is using router at all).
  
In your `package.json` modify your scripts settings like this:

```
"scripts": {
    "serve:web": "vue-cli-service serve src/web/main.js",
    "serve:mob": "vue-cli-service serve src/mob/main.js",
    "build:web": "vue-cli-service build --dest dist_web src/web/main.js",
    "build:mob": "vue-cli-service build --dest dist_mob src/mob/main.js",
    //other scripts...
},
```

We will have separate commands for serving/building web and mobile apps.
For serve we just provide entry point (which is now different in both cases, than default one), and for build we have to provide destination folders as well, so they don't overwrite each other.

In shared folder, all of our shared component logic will reside, as most of it are just functions that are imported in respective components where they are to be used (so in both web and mobile components).

It's up to you to decide if store should be global for both apps, or if it should be app scoped, depends on the use case I guess.

So now we have our folder structure, and serve/build commands, so we can treat them as separate apps and they will behave as such. But shared logic will be used from one place following the DRY principles, which is much easier to maintain than having 2 completely different projects and copying a certain amount of potentially same code across codebases.

If you want to dive deeper, test project can be found at [github](https://github.com/PerpetualWar/vue-shared-app).

Comments are welcome, and thanks for reading.