Skip to content

feat: migrate Vue 2 to Vue 3 via @vue/compat (MODE 2)#314

Draft
AgustinRamiroDiaz wants to merge 15 commits intoSTS-Rosario:masterfrom
AgustinRamiroDiaz:feat/new-vue3-migration-with-compat
Draft

feat: migrate Vue 2 to Vue 3 via @vue/compat (MODE 2)#314
AgustinRamiroDiaz wants to merge 15 commits intoSTS-Rosario:masterfrom
AgustinRamiroDiaz:feat/new-vue3-migration-with-compat

Conversation

@AgustinRamiroDiaz
Copy link
Contributor

@AgustinRamiroDiaz AgustinRamiroDiaz commented Feb 23, 2026

Summary

Migrate frontend from Vue 2 to Vue 3 using @vue/compat in MODE 2 (Vue 2 behavior preserved). All ~80 existing .vue components, Vue 2 plugins, filters, directives, and event bus continue working as-is under compat mode with deprecation warnings in the console.

Core migration changes

File Change
package.json Update vue/vuex/vue-router/vue-i18n/vue-loader to v3 ecosystem; add @vue/compat, @vue/compiler-sfc, entities; pin vue-router@4.3.3
build/webpack.base.conf.js VueLoaderPlugin import, vue@vue/compat alias, vue-loader compat options
src/i18n.js New — extracted i18n config from main.js to break circular dependency (main → router → main)
src/store/index.js new Vuex.Store()createStore()
src/router/index.js new VueRouter()createRouter() with createWebHashHistory
src/router/routes.js Catch-all route /*/:pathMatch(.*)*
src/main.js createApp() + app.use() mounting; removed inline i18n setup
src/services/bus-event.js Guard _events access (undefined in Vue 3 compat)
Dockerfile Node 12 → Node 18; --legacy-peer-deps --ignore-scripts for Vue 2 plugin compat

Vue 3 syntax fixes

File(s) Change
src/components/sections/HeaderApp.vue Fix v-for/v-if priority (Vue 3 evaluates v-if first); update slot="name"#name for dropdown/modal slots
src/components/views/Trip.vue Move :key from child to <template v-for>
src/App.vue Remove stale margin-top: 60px on #app
22 components Migrate old slot="name" syntax to <template #name> — compat mode does not handle this correctly, causing Loading states and modal slots to render in the wrong place

CI & config

File Change
.npmrc legacy-peer-deps=true — fixes npm ci failure from vue2-google-maps peer dep conflict
.gitignore Add .env

What stays unchanged (compat handles it)

  • All .vue component logic ($set, beforeDestroy, Vue.filter(), Vue.prototype, Vue.directive(), etc.)
  • All Vue 2 third-party plugins (vue-moment, vue-strap, vue2-leaflet, v-mask, vue-analytics, vue-head, etc.)
  • Event bus ($on/$off/$emit)

Test plan

  • npm run dev compiles successfully (deprecation warnings only, 0 errors)
  • All 8 Playwright e2e tests pass (login, navigation, trips, create-trip, full trip-request-flow with 6 users)
  • Smoke test: login → browse trips → trip detail → create trip → conversations
  • npm run build — production build succeeds

🤖 Generated with Claude Code

@AgustinRamiroDiaz AgustinRamiroDiaz force-pushed the feat/new-vue3-migration-with-compat branch from 9e1a947 to 970f032 Compare February 23, 2026 17:42
@AgustinRamiroDiaz AgustinRamiroDiaz marked this pull request as ready for review February 23, 2026 18:22
@AgustinRamiroDiaz
Copy link
Contributor Author

@GonzaloGM ready for review!

If we go ahead with this PR, then we can go module by module with the upgrades to vue3 🥳

@GonzaloGM
Copy link
Contributor

@AgustinRamiroDiaz thanks a lot! It looks good but it seems there are some visual changes. For example I see that the font used is Avenir when we're using Roboto. Also, texts seem centered by default, we should make them left aligned.

We have some graphs in admin that aren't working, but not sure if that was planned for a later PR, it'd be good to have it now so we don't lose visibility of that for admins in the migration.

@AgustinRamiroDiaz
Copy link
Contributor Author

@GonzaloGM fixed alignment, I'm now reading about the graphs in admin
I think we'll need to upgrade the graphics library vue-chart-3 to v5 (which is vue3 compatible) since the current v3 uses internals of vue2 (which are not handled by vue compat).
sounds good? I think I'll be able to implement it

@GonzaloGM
Copy link
Contributor

@AgustinRamiroDiaz Yeah that sounds great, thanks!

@GonzaloGM
Copy link
Contributor

@AgustinRamiroDiaz I checked the PR, this looks good, once the graphs are fixed we can merge I think!

@AgustinRamiroDiaz
Copy link
Contributor Author

AgustinRamiroDiaz commented Feb 24, 2026

@GonzaloGM I've addressed those issues. Check the admin panel now

@AgustinRamiroDiaz
Copy link
Contributor Author

AgustinRamiroDiaz commented Feb 24, 2026

I'll be creating issues for all the upgrades for the packages so that we can remove vue/compat

This was referenced Feb 24, 2026
@GonzaloGM
Copy link
Contributor

@AgustinRamiroDiaz Great I'll test it, the individual issues descriptions have the description missing I Think? or where are those issues .md files?

@AgustinRamiroDiaz
Copy link
Contributor Author

@AgustinRamiroDiaz Great I'll test it, the individual issues descriptions have the description missing I Think? or where are those issues .md files?

damn, I'll fix that

Also, do you know how can I test Capacitor?

@GonzaloGM
Copy link
Contributor

GonzaloGM commented Feb 24, 2026

@AgustinRamiroDiaz these are the commands I used to build the apps in my devices:

BUILD ANDROID: cd ~/Work/carpoolear/carpoolear && npm run build:android && cp -r dist/default/production/www/* www/ && npx cap run android --target d59fb3c7

/Users/gonzalogm/Work/carpoolear/carpoolear/android/app/build/outputs/bundle/release
BUILD IOS: cd ~/Work/carpoolear/carpoolear && npm run build:ios && cp -r dist/default/production/www/* www/ && npx cap run ios --target "00008030-001D71E11128802E"

you'll have to change your device IDs though

/EDIT: this is what I used for building Android for the store, not sure about iOS as I wasn't able to build it because Apple doesn't allow multiple building devs in individual accounts (Pablo did).

cd ~/Work/carpoolear/carpoolear && npm run build:android && cp -r dist/default/production/www/* www/ && cd ~/Work/carpoolear/carpoolear/android/ && ./gradlew bundleRelease

I was able to build for Android, I'll see if Pablo can test building in iOS and we can merge.

@AgustinRamiroDiaz
Copy link
Contributor Author

thanks! I've installed android studio and configured my machine. I was able to emulate the android build 🥳

I don't have IOS to test :(

@AgustinRamiroDiaz
Copy link
Contributor Author

@GonzaloGM tested on android and it seems to be working 👍

  1. I've noticed that the admin panel is not accessible through the android app

  2. I've done some stuff in order to be able to test against the dev backend. Do you do these as well or do you only test against prod backend?

  A. Gradle JDK path (android/gradle.properties)

  Changed macOS JDK path to Android Studio's embedded JBR:
  - org.gradle.java.home=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
  + org.gradle.java.home=/opt/android-studio/jbr

  B. Cleartext HTTP traffic (android/app/src/main/AndroidManifest.xml + new
  network_security_config.xml)

  Added network security config to allow HTTP to the emulator host:
  - Created android/app/src/main/res/xml/network_security_config.xml allowing cleartext to 10.0.2.2 and
   localhost
  - Added android:networkSecurityConfig attribute to AndroidManifest.xml

  C. Mixed content (capacitor.config.json + MainActivity.java)

  The app loads under https://localhost (Capacitor's androidScheme), which blocks HTTP API calls. Fixed
   by:
  - Added "allowMixedContent": true to capacitor.config.json
  - Added WebSettings.MIXED_CONTENT_ALWAYS_ALLOW in MainActivity.java (the config alone wasn't
  sufficient)

@GonzaloGM
Copy link
Contributor

@AgustinRamiroDiaz I usually just change the API backend to an ngrok and test locally, but it that makes it work with localhost and prod, great! :)

@GonzaloGM
Copy link
Contributor

GonzaloGM commented Feb 25, 2026

@AgustinRamiroDiaz I tried testing the Sellado which is a new feature not enabled in public now, but already in master (just disabled via feature flags in prod), which enables payment (via Mercado Pago CheckoutPro API) on trip creation for some trips, and it has stopped working with a weird error that I can't seem to fix:

(anonymous) @ app.d2c265a3200347f01b92.js:1Understand this error walletButton.js:1

This is on a trip detail page in a trip that has sellado (Rosario->Buenos Aires with sellado enabled in backend). There should be a MP payment button (the classic yellow one) but it doesn't load and gives that error. If I switch to master it works, really strange.

This is working in master, I just tested it, but in this branch it's not. To be honest it's really strange, I've been trying to find the cause for a few hours and no luck, the diff in this file is pretty much Vue3 migration stuff. I'm available to discuss over Discord or some other way if you want.

@AgustinRamiroDiaz
Copy link
Contributor Author

@GonzaloGM could the Sellado issue be due to this branch not being up to date with master? I'll rebase and try that

I'd be happy to improve our communication through discord
Ping me at agustinramirodiaz

@AgustinRamiroDiaz AgustinRamiroDiaz force-pushed the feat/new-vue3-migration-with-compat branch from 7d0b9ce to 58f1fe0 Compare February 26, 2026 13:34
@AgustinRamiroDiaz AgustinRamiroDiaz marked this pull request as draft February 27, 2026 13:38
@AgustinRamiroDiaz
Copy link
Contributor Author

converting to draft until I fix the Sellado feature

@AgustinRamiroDiaz AgustinRamiroDiaz force-pushed the feat/new-vue3-migration-with-compat branch from 58f1fe0 to 0df5a22 Compare February 27, 2026 13:38
AgustinRamiroDiaz and others added 13 commits February 28, 2026 15:50
Migrate the frontend to Vue 3 using the compatibility build (@vue/compat)
in MODE 2, which preserves Vue 2 behavior while enabling the Vue 3 runtime.
All existing components, plugins, and patterns continue to work as-is with
deprecation warnings in the console.

Key changes:
- Update vue, vuex, vue-router, vue-i18n, vue-loader to Vue 3 ecosystem
- Use createApp/createStore/createRouter/createI18n APIs
- Extract i18n config to src/i18n.js to break circular dependency
- Fix v-for/v-if priority change in HeaderApp.vue (Vue 3 breaking change)
- Fix bus-event.js for Vue 3 compat (_events internal property)
- Fix template :key placement in Trip.vue for Vue 3 compiler
- Update catch-all route to Vue Router 4 syntax
- Pin vue-router@4.3.3 (4.4+ uses optional chaining unsupported by Babel 6)
- Upgrade Dockerfile from Node 12 to Node 18
- Remove stale margin-top: 60px on #app

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add .npmrc with legacy-peer-deps=true to fix npm ci failure caused by
vue2-google-maps requiring vue@^2 as peer dep. Update old slot="name"
syntax to #name in HeaderApp.vue so vue-strap dropdown slots render
correctly under Vue 3 compat.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Vue 3 compat mode does not properly handle the old slot="name" attribute
syntax on non-template elements, causing slot content to fall into the
default slot. This made Loading states (no-data, loading) always visible
and modal header/body slots render incorrectly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…8n keys

Consolidate two separate `import` from 'vue' into one to fix
import/no-duplicates. Remove 15 duplicate translation keys across
arg/chl/en locales in i18n.js to fix no-dupe-keys (pre-existing on master).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract dismissOverlays and uiLogin into shared e2e/helpers.js
- Replace API-based cleanup with UI interactions (Cancelar Viaje button)
- Remove API_URL constants from test files
- Use user9 as driver in trip-request-flow to isolate from create-trip test
- Add try/catch in route.fetch handlers to prevent context disposal errors
- Increase login redirect timeouts to 15s for parallel stability

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace bind/unbind with beforeMount/unmounted (Vue 3 lifecycle hooks)
- Use binding.value instead of vnode.context[binding.expression]
  (vnode.context was removed in Vue 3)
- Add Playwright test that reproduces and verifies the fix
@AgustinRamiroDiaz AgustinRamiroDiaz force-pushed the feat/new-vue3-migration-with-compat branch from e5b2071 to 3bf235f Compare February 28, 2026 18:50
@AgustinRamiroDiaz
Copy link
Contributor Author

@GonzaloGM I was able to test almost the entire flow, but I'm missing the callback since I cannot run 2 ports with ngrok

I have been able to

  • see mp button on third trip
  • click it
  • pay it

How do you have the setup done with ngrok?
I'm now trying other alternatives, but I'm not able to make them work yet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants