Planning to migrate from Angularjs to Vue? by Shailee Mehta on April 9, 2020 1,190 views
It is an essential part of a software development cycle to keep the tech stack updated, and with so many frameworks a movie buff like me would say it is a real Sophie’s choice…
This blogpost is for product owners or developers working on Angularjs, looking for answers to which technology to upgrade to. Whether to stick to Angular and move a version up or pick a new framework. The following blog post says why it is better to move to Vue, followed by a detailed tutorial on how to smoothly transition from the former to the latter.
Answering the why…
Source: https://www.meme-arsenal.com/en/create/meme/544093
When picking a frontend framework there is no absolute best. The best framework is the one that suits your needs the best. For us the main reason was Vue’s easy learning curve and quick onboarding due to similarities in syntax between Vue and angularjs. So, if you have already made up your mind to migrate your angularjs app to Vue read ahead.
Contents
The migration of any application is done feature-wise. The basic app is built first then we migrate one screen at a time. So there will be times when a part of the app is in AngularJs and the other is in Vue. There are a few things like route handling, session management which need to be managed.
Here is a list of tweaks this blogpost mentions:
- Set up the primary application
- Routing
- Session management and data sharing across both apps
Set up the primary application
The first thing you need to do is to set up a basic Vue application in your project. Create a separate frontend folder (or any name which you like to keep) for Vue. Here you can use Vue-CLI tools for the boiler-plate code. Or you can set up the app as needed. We do not need to write a login and user management code at this point. Make sure you fetch all the data that is absolutely necessary to run a user session.
Here’s what we did to separate out our Vue application from the angular. There are two parts to this application. One that we run in development mode, we have a nuxt server running for Vue; While the second is the production build. The separate folder for Vue runs on a Nuxt development server, so it has its own build.
Here, when in development mode the project runs on Nuxt otherwise it renders a static build file.
// Instantiate the NuxtJs during development only. // In production, we serve static files generated by "nuxt build" if (/DEVELOPMENT/.test(app.get('ENV_CONTEXT'))) { require('../frontend/nuxt-start.js')(app).then(() => { listen(); }); } // In production mode there is no nuxt, so we must capture // any uncaught routes, just like nuxt would, and serve the // Nuxt index file. else if (/PRODUCTION|TESTING/.test(app.get('ENV_CONTEXT'))) { app.use('*', function(req, res, next) { res.sendFile(path.resolve('static/200.html')); }); }
So In development mode, a Nuxt server is deployed which enables hot reloading. Whereas for deployment, we use the Nuxt command npx nuxt build
to generate static files and render them on this first call to the server.
Since SEO was not important for most of our projects we prefer the Vue application in SPA mode. That is, there is only one index file served by the server and the rest of the routes are handled by the browser side router.
Once you have this, we need ways to land on the homepage of your Vue application from your Angular application.
Routing
To keep the checks on routing intact and not to break and validations we do not override the route itself but we redirect to the Vue app after the current angular route is rendered. Also, it saves the effort of handling the route redirection from multiple places.
Here is a redirect method we wrote for one of the apps that we migrated to Vue.
function redirect({ moduleName, routes }) { const app = typeof moduleName === 'object' ? // An actual angular module was supplied moduleName : // A module name was supplied, so, we create a new module angular.module(moduleName, []) app.config([ '$stateProvider', $stateProvider => { /* routeName, fromUrl, toUrl, stateParam */ if (!(!!routes && routes.length > 0)) return routes.forEach(route => { let routeName = route.routeName $stateProvider.state(routeName, { url: route.fromUrl, resolve: { _nuxt: ($stateParams) => { window.location = route.toUrl; return Promise.reject('redirect: ' + route.toUrl) }, }, }) }) }, ]) }
This method accepts a list of routes and on a resolution of the route, it is redirected to the related Vue page. Use this method with the app config to redirect any route to Vue and remove the state defined in the app.config.
const app = angular.module('kpmgSophia.object') app.config(function config($stateProvider) { $stateProvider .state('admin/objects', { url: '/admin/objects', views: { main: { controller: 'ObjectBusinessRuleCtrl', templateUrl: 'admin/objects/partials/objects.businessRule.tpl.html', }, }, }) }) redirect({ moduleName: objectApp, routes: [ { routeName: 'admin/objects', fromUrl: '/admin/objects', toUrl: `${location.origin}/admin/objects`, }, ], })
Session management and data sharing
For the migration, it is better to first migrate all the features and then add the login feature. So every time a session expires or a user logs out, the app must be redirected to the angular login page.
Now there are use cases where some data has to persist over the session such as user credentials. These we generally store in the browser’s local storage. This same storage can be used for sharing global variables. For example, a custom user setting of whether a sidebar should stay collapsed. Let us say the default behavior is to keep the sidebar expanded. But in the current logged-in session, the user set toggled the setting. Now if this was done when in the Angular side of the app, how to persist it while switching to the Vue app. Here is where the local storage comes handy. Remember this is an extra tweak you are adding to the application so, be sure to remove it once the project is completely migrated to Vue.
Here is an example of how we did it. Following is our Vue code. A Vue watcher in which a session variable is set every time the user toggles the sidebar setting. Also to set the sidebar state, it reads from the storage for every route change. Also for server-side session data, you can always call an API when the app loads. Use either approach as suited by the use case.
data() { return { showNavDrawer: false, showFilterDrawer: false, miniDrawer: this.getMiniCookie(), isMini: this.getMiniCookie() }; }, methods: { getMiniCookie() { const cookieValue = getCookie('minimise') || false; return cookieValue === 'true'; } }, watch: { $route(to) { this.isMini = this.getMiniCookie(); }, miniDrawer(nv) { setCookie('minimise', nv + ''); this.isMini = nv; } }
See it is that easy…. In conclusion, there are three things to watch out for, the foremost is deployment and serving, second is navigating between the two applications and the third is data sharing between the applications. And you’re good to go.
I hope this blogpost removes any of the reservations there are about the efforts migrating your application and motivates you to move to VueJs. Happy coding! 🙂
Stay tuned for regular updates on our technology!
Feel free to share your thoughts in the comment box. You can connect with us for a free consultation!