How to merge Angular and Vue projects together?

2020-02-28 06:13发布

I read various resources available on this but still couldn't figure out a way. The issue here is that I want to merge two different projects together. My colleague was working on one feature which he designed in AngularJS. I developed my feature using VueJS. The management then decided that both of them should be merged together. As in, From the UI where the first project is launched, there would be a link provided from where my webpages designed in VueJS would launch.

I am running my project locally on VueJS server using npm start and also using express server as well. But first project only runs node app.js and it runs in local then.

Below is the screenshot of his project description:

enter image description here

And this is my project details:

enter image description here

My index.html file has these contents:

<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Error Details and Description</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  </head>
  <body>
    <div id="app"></div>
    <script src="bundle.js"></script>
  </body>
</html>

The other index.html contained in first project has code for that link through which my app would launch. The link contains this code which can redirect to my code:

<li><a><i class="fa fa-edit"></i>Administration<span class="fa fa-chevron-down"></span></a>
                        <ul class="nav child_menu">
                          <li><a href="#!errorinput"><i class="fa fa-database"></i>Manage Error Descriptions</a></li>

The corresponding errorinput.js file contains this code:

'use strict';

app.config(function ($routeProvider) {
    $routeProvider
        .when("/errorinput", {
            templateUrl: "views/errorinput.html"
        });
});


app.controller('ErrorInputCtrl', ['$scope', '$http', function ($scope, $http) {
 // Implement me!
}]);

Any idea how to merge both of them together to get the required functionality?

EDIT: So I did found a way to run both projects on one server. I included all the dependencies of AngularJS inside my VueJS project. The angular app was running fine but now, the VueJS webpage doesn't comes up along with angularJS. It appears to coming in background when I give relative path of my VueJS app. Any idea how can I now route my VueJS in this bootstrapped AngularJS app? More details about this issue is mentioned here:

more details

2条回答
戒情不戒烟
2楼-- · 2020-02-28 06:59

And they are entirely independent from each other as well. There is no link in the first project app from where my app needs to be launched.

It seems like you can try out the cool Micro Frontend. MicroFrontend is a new application paradigm where frontend services are organised as different applications and communicate through an event bus all on the front end.

There are different methods of achieving this like:

  1. Rendering them in different iFrames and communicating through an postMessage API
  2. Rendering them at different URLs but using an event bus with common dependency management.
  3. Using single SPA Framework.

Since you said that the applications need not communicate with each other, SPA Framework would be easier for you. It is very mature framework in this domain with support for front end frameworks including Vue and AngularJS but not limited to these options.

What you would do to make this work is effectively create an HTML with different divs:

<div id="angular1"></div>
<div id="vue-app"></div>

So that they do not involve changes with each other.

Create a single SPA file as config of your application.

import * as singleSpa from 'single-spa';

singleSpa.registerApplication('angular', () =>
  import ('../app1/angular1.app.js'), pathPrefix('/app1'));
singleSpa.registerApplication('vue', () =>
  import ('../app2/vue.app.js'), pathPrefix('/app2'));

singleSpa.start();

function pathPrefix(prefix) {
  return function(location) {
    return location.pathname.startsWith(`${prefix}`);
  }
}

You can find more details on this config Here

After installing the corresponding SPA plugins (single-spa-vue and single-spa-angular in your case), we have to tell single-spa the life cycle hooks it needs to mount and unmount your framework.

In the case of vue:

import Vue from 'vue/dist/vue.min.js';
import singleSpaVue from 'single-spa-vue';

const vueLifecycles = singleSpaVue({
  Vue,
  appOptions: {
    el: '#vue-app'
    template: `<p>Vue Works</p>`
  }
});

export const bootstrap = [
  vueLifecycles.bootstrap,
];

export const mount = [
  vueLifecycles.mount,
];

export const unmount = [
  vueLifecycles.unmount,
];

You can find a sample application with Vue and Angular Here. Here is a step by step guide from makers of single-spa. Also check out their examples.

Hope that helps.

查看更多
放荡不羁爱自由
3楼-- · 2020-02-28 07:00

One solution would be to continue to keep the two features (really applications) separate and divert the user traffic with a Load Balancer. The load balancer can handle and route traffic to the respective application based on configured URL rules. If you are using AWS, you can configure an Application Load Balancer (ALB) using listener rules and target groups.

Even if you aren't using AWS, this type of load balancer can be easily configured. For example with a reverse proxy server on nginx.

The benefit of this approach is that neither application needs to be updated at all, and you don't have to worry about any cross-framework dependencies, issues, etc.

Example:

applicationname.com/app1 -> forwards to Target Group for App 1
applicationname.com/app2 -> forwards to Target Group for App 2

In each application you can now just use regular href links that can point to the other application. example in App 1: <a href="/app2/feature1">Feature 1</a>

查看更多
登录 后发表回答