Skip to content

Draft: migrate to Nuxt 3 / Vue 3

Valentyne Stigloher requested to merge 372-nuxt3-migration into main

State of this MR

most of the things should work, the most noticeable todo are the wrong paddings / spacings. some nuxt modules and 3rd party vue plugins still need migration

this is a rather chaotic MR – the commits should contain what they are labelled as but are in the order of how simple I found to do this change – not necessarily the order in which makes it sense. the last wip commit is a “all the stuff which I need to apply to make it working” and will be sorted later.

expect frequent rebases here, so if you want to help out here (much appreciated), please reach out to me first so we don’t generate conflicts by accident 😄

Links

https://v3-migration.vuejs.org/ https://nuxt.com/docs/migration/overview

Check list

🏃 means incomplete

Infrastructure

  • change packages
  • use nuxi instead of nuxt
  • typescript fixes
  • linting fixes
  • integrate tests (Jest or vitest)

Vue

  • change lints from plugin:vue/recommended to plugin:vue3/recommended
  • migrate from Vuex to Pinia
  • migrate from Babel + Webpack to Vite \
  • replace Vue.prototype with other mechanism (probably config.globalProperties)
  • use @update:modelValue and modelValue for v-model
  • remove .native modifier
  • define custom events in emits
  • replace $on
  • import h instead of having it as parameter in render
  • change $slots
  • replace eventHub
  • replace now unnecessary vue-ignore and ts-ignore inside <template> with proper typing (Vue 3 doesn’t allow Typescript inside templates)
  • use whitespace removal rule preserve as the default condense puts elements too close together because we rely on some implicit spaces – (we probably want condense in cases like <Popover>, but let’s postpone it)
  • replace <LazyHydration>
  • replace <DateTimePicker>
  • check RTL

Nuxt

  • migrate configuration
  • replace head with useHead()
  • replace axios with $fetch and higher-level utilities
  • replace $cookies with useCookie and friends
  • replace sentry module 🏃 missing: release management
  • migrate plausible module
  • migrate pwa module
  • migrate csrf module
  • integrate Express
  • check that 404 works like expected
  • investigate problems with sharp and canvas, maybe something to do with https://sharp.pixelplumbing.com/install#esbuild?
  • investigate problems with __dirname / import.meta.url referencing wrong directory
  • think about integration of new → server handler approach should work for fastify too
  • rename directories
  • remove env from nuxt.config.ts
  • figure out solution for /img-local/census only used by pl but still present in <Header> and thus Vite throwing an error
  • migrate loading indicator (or just use the default for now)
  • investigate why ssr is not working → using h3-express and adjusting some calls solves this
  • don’t access the Nuxt context after an await (e.g. blogEntry.vue)
  • investigate problems with nepali-calendar-js → it defines variables in global scope, and I forked it for that (will do a PR there)
  • migrate no-ssr middleware
  • migrate atom middleware
  • check imports in pl/calendar
  • wait for https://github.com/hidekatsu-izuno/h3-express/pull/3 – workaround: clone locally, run npm instal && npm run build, then reference this via local dependency in package.json
  • investigate missing source files in source map of /routes/profileEditor.vue
  • check error hooks
  • investigate crypto polyfill: with it, production bundle fails with something like exports not defined, without it, login does not work
  • redirect (did it the wrong way round)

Deployment

  • figure out deployment (pm2 or simpler for now?)
  • figure out dotenv importing (Nuxt does not do it automatically and __INCLUDE is our own mechanism)
  • move static/calendar to public/calendar

Test

  • Test, test, test! (manually is okay)

Notes

  • Vite apparently was easier then Webpack to get running, but we may want to consider to put the plugin for .suml into another repo and use some off-the-shelf solution for .tsv
  • Vite didn’t like createRequire and it still might be possible to use the string-replace-attempt I did in Webpack but it felt very, very wrong to migrate this crutch. but at least Vite can handle import with { type: 'json' } – node still experimental so if that is a deal breaker we can resort to string replacement again
  • typings improved a lot due to Pinia and Vue 3 for the frontend 🎉
  • apparently, Nuxt 4 is already visible on the horizon, but the changes from v3 to v4 shouldn’t be too big, so I’d prefer to first migrate to Nuxt 3, getting us into supported land again and then make the adjustments needed for Nuxt 4 https://nuxt.com/docs/getting-started/upgrade

Known Issues

  • sometimes, when updating nuxt.config.ts it complains that a module is not registered from canvas.node. I couldn’t figure out the reason (maybe have to ignore this package in more places than nitro), but just restarting the dev server works

Helpers

some commands I need regularly when stuff on main has changed

  • sed -i -E "s/Vue\.extend/defineComponent/" **/*.vue && sed -i -E "s/import Vue from 'vue'/import { defineComponent } from 'vue'/" **/*.vue
  • sed -i -E "s/\\\$config/config/" **/*.vue
  • git restore --staged pnpm-lock.yaml && git restore pnpm-lock.yaml && pnpm install && git add pnpm-lock.yaml

Closes #372

Edited by Valentyne Stigloher

Merge request reports