Skip to content

Commit aa7946d

Browse files
committed
Add the first rough draft
1 parent 6363147 commit aa7946d

File tree

1 file changed

+245
-0
lines changed

1 file changed

+245
-0
lines changed
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# 2023-06-01 Implementation Plan: Nuxt 3 Migration
2+
3+
**Author**: @obulat
4+
5+
<!-- See the implementation plan guide for more information: https://github.com/WordPress/openverse/tree/19791f51c063d0979112f4b9f4eeace04c8cf5ff/docs/projects#implementation-plans-status-in-rfc -->
6+
<!-- This template is exhaustive and may include sections which aren't relevant to your project. Feel free to remove any sections which would not be useful to have. -->
7+
8+
## Reviewers
9+
10+
<!-- Choose two people at your discretion who make sense to review this based on their existing expertise. Check in to make sure folks aren't currently reviewing more than one other proposal or RFC. -->
11+
12+
- [ ] @sarayourfriend - for extensive experience with JS
13+
- [ ] @zackkrida - for extensive frontend experience and the previous migration
14+
to Nuxt
15+
16+
## Project links
17+
18+
<!-- Enumerate any references to other documents/pages, including milestones and other plans -->
19+
20+
- [Project Thread](https://github.com/WordPress/openverse/issues/411)
21+
- [Project Proposal](https://docs.openverse.org/projects/proposals/nuxt_3_migration/20230604-project_proposal_nuxt_3_migration.html)
22+
23+
## Overview
24+
25+
<!-- An overview of the implementation plan, if necessary. Save any specific steps for the section(s) below. -->
26+
27+
Nuxt team has created Nuxt bridge to facilitate the migration from Nuxt 2.
28+
However, there seems to be
29+
[no support for Nuxt Bridge in Nuxt i18n](https://github.com/nuxt-modules/i18n/discussions/1334#discussioncomment-1967220),
30+
so the best way forward is to migrate directly to Nuxt 3.
31+
32+
Nuxt 3 migration will require a lot of changes split into several PRs.
33+
34+
One set of changes is required for Nuxt 3, but can also work in the current Nuxt
35+
2 app. An example of such change is the conversion of `onBeforeRouteEnter` to
36+
`middleware`: both work well in Nuxt 2, but only `middleware` can access `store`
37+
in Nuxt 3. These changes are described in the "Changes to main" section below,
38+
should be merged directly into `main` branch.
39+
40+
The other changes like actually updating the `nuxt` version would break the
41+
current app. To make sure that we can split these changes into several distinct
42+
steps without breaking the production app, we should use a separate branch,
43+
`nuxt3`, that would gradually get more and more features re-enabled.
44+
45+
### Nuxt 3 / Vue 3 features in Openverse: discussion
46+
47+
#### Autoimports
48+
49+
Nuxt 3 auto imports composables and components. Unlike the usual global imports,
50+
these imports are handled in such a way that only the imports that are actually
51+
used are left in the production files. The Nuxt team have optimized the way they
52+
work both in the working app and in the IDEs, so I think we _should_ use the
53+
auto import feature and not go against the framework and disable it. In the
54+
current setup, our test suite throws warnings when a child component is not
55+
imported. We would need to make sure that this does not happen with Nuxt 3.
56+
57+
#### `script setup`
58+
59+
The new way of writing components in Vue 3 is using `script setup` which reduces
60+
the number of code lines by automatically exporting the variables for use in the
61+
components. While we can eventually move to using `script setup` throughout the
62+
app, this conversion is out of scope for this project. We can, however, convert
63+
some components if they need extensive code changes anyways, or if the behavior
64+
within them changes significantly and the `script setup` simplifies the
65+
component. The decision wether to convert components to `script setup` would be
66+
at the discretion of the PR implementer.
67+
68+
#### Testing
69+
70+
Vue 3 recommends to use Vitest for better performance and integration with
71+
`vite` (which will replace `webpack` in our setup). I have not had an
72+
opportunity to test it out, but I think it would make sense to convert our unit
73+
tests to `Vitest`. The decision on whether to keep using the current
74+
dependencies or convert to `Vitest` should be based on the ease of conversion.
75+
76+
### Changes to main
77+
78+
- Replace `onBeforeRouteEnter` router guards that don't have access to `pinia`
79+
stores with router `middleware` that does #2234
80+
- Deprecation of CJS modules (the ones that use `require` and `module.exports`):
81+
- `case` package that we use for `kebab-case`, `title` case and `camelCase`
82+
function is CJS. We can either find replacements that use `ESM` modules,
83+
vendor in these functions, or use a workaround that `vite` suggests (instead
84+
of `const { kebab } = require "case"` use
85+
`import casePkg; const { kebab } = casePkg;`)
86+
- home gallery uses `require` when importing the images dynamically. There is
87+
a small number of them, so we should just move them to `static` folder (or
88+
`public` in Nuxt 3) and use static `import`s.
89+
- Tailwind config should be converted to TypeScript.
90+
- Remove old unused modules and code
91+
- `@nuxtjs/style-resources` - this module was used to auto-import `scss`
92+
variables into all components. We don't use `scss` anymore
93+
- Audit and remove the code that was used with old designs or with for work
94+
with the iframe.
95+
- Refactor `search.vue` page: move the route watcher and `fetchMedia` functions
96+
to `setup`
97+
- Refactor image and audio single result pages to show the skeleton page when
98+
the "image"/"audio" is `null`. This is required because the way data is
99+
fetched changes, and _is_ the correct way it _should_ be set up (instead of
100+
not handling the case of `image` being `null` and instead relying on the error
101+
page redirect)
102+
103+
### Changes in Nuxt 3 branch
104+
105+
- The first PR should update the bare minimum to get the app working with Nuxt
106+
3:
107+
- update `nuxt` itself and `i18n`, `tailwind` and `svg-sprite` modules (and
108+
the way they are set up). Remove/comment out other modules, plugins,
109+
middleware.
110+
- update the Typescript config and node version.
111+
- Move the functions that are called at the app set up from
112+
`middleware`/`layout`s to `app.vue`.
113+
- Convert the layouts and pages to use `NuxtPage` instead of `NuxtChild` and
114+
`slot` instead of `Nuxt`. For other necessary changes, look up the Nuxt 3
115+
docs.
116+
- Use the new way of declaring `async components`
117+
- Remove `Vue.set`
118+
- Move `key` from items inside a `v-for` to the surrounding `template`. This
119+
PR would produce an app version that can be run with the `pnpm dev` or
120+
`pnpm build && pnpm start` commands, but would have significantly less
121+
functionality and many console errors/warnings, so it would probably be
122+
pushed using `--no-verify` git flag.
123+
- Set up unit tests and add `.skip` to all the tests that are failing.
124+
Temporarily remove the setting that disallows error logs in the test console.
125+
- Correctly set up the head using `useHead` and `i18n`
126+
- Remove the `@nuxtjs/composition-api` imports, replacing them with the
127+
corresponding `useNuxtApp` or `i18n` import. If not yet possible, comment out
128+
the import and the functionality that uses it.
129+
- Remove all `v-on="$listeners"`, making sure that the `on` handlers are still
130+
passed to the correct component/element.
131+
- Remove the `.native` modifiers, and convert `VLink` to use `NuxtLink`. The
132+
`VButton` that has `as="VLink"` can be tricky here, so we would need to make
133+
sure it works.
134+
- Rewrite data fetching to use the new `useAsyncFetch` composable.
135+
- Re-add the modules listed in the "Modules" section.
136+
137+
## Expected Outcomes
138+
139+
<!-- List any succinct expected products from this implementation plan. -->
140+
141+
Openverse frontend uses Nuxt 3, and all current features (including i18n,
142+
sitemaps, SEO) work.
143+
144+
## Outlined Steps
145+
146+
<!-- Describe the implementation step necessary for completion. -->
147+
148+
- [x] Plan for Nuxt modules updates ✅ 2023-06-01
149+
- [ ] Add changes that can be done in Nuxt 2 (see "Changes to main")
150+
- [ ] Create a `nuxt3` branch with the first PR as described in the "Nuxt 3
151+
branch"
152+
- [ ] Add all other Nuxt 3 changes, as described in the "Nuxt 3 branch"
153+
- [ ] Re-enable Playwright tests
154+
- [ ] Make all unit tests pass
155+
156+
## Dependencies
157+
158+
### Vue 3 breaking changes
159+
160+
<!-- Describe any infrastructure that will need to be provisioned or modified. In particular, identify associated potential cost changes. -->
161+
162+
- [ ] `v-model`
163+
[changes](https://v3-migration.vuejs.org/breaking-changes/v-model.html)
164+
- [ ] `key` usage on `template v-for` instead of the components inside that
165+
`template`
166+
- [ ] [`v-on:event.native` removed](https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html) -
167+
after removing `.native`, check that links work as expected, sending the
168+
analytics events
169+
- [ ] [`$listeners` has been removed / merged into `$attrs`](https://v3-migration.vuejs.org/breaking-changes/listeners-removed)-
170+
remove the `$listeners` everywhere and make sure that we have
171+
`v-bind="$attrs"` everywhere we had `$listeners` before
172+
- [ ] [`$attrs` includes `class` & `style`](https://v3-migration.vuejs.org/breaking-changes/attrs-includes-class-style.html) -
173+
remove `v-bind="$attrs"` from the root element in components where
174+
`inheritAttrs="false"`
175+
- [ ] `Vue.set` is not necessary anymore to keep array/object reactivity
176+
- [ ] [async components change of syntax](https://v3-migration.vuejs.org/breaking-changes/async-components.html)
177+
(for components that use `Comp = () => import("component.vue")`)
178+
- [ ] [`emits` option](https://v3-migration.vuejs.org/breaking-changes/emits-option.html) -
179+
replace the `defineEvents` custom implementation
180+
181+
### Nuxt 3 breaking changes
182+
183+
- [ ] `NuxtLink` is now a wrapper around both external and internal links, so we
184+
can replace our custom `VLink` component with it.
185+
- [ ] `app.vue` is a single place where we can put the code that needs to run
186+
once when the app starts up. Currently, we have some layout code that is
187+
duplicated, and `middleware` code that is run before the first load. We
188+
should move it to `app.vue`
189+
- [ ] [Pages and layouts changes](https://nuxt.com/docs/migration/pages-and-layouts)
190+
191+
### Tools & packages
192+
193+
<!-- Describe any tools or packages which this work might be dependent on. If multiple options are available, try to list as many as are reasonable with your own recommendation. -->
194+
195+
[`nuxt-vitest`](https://github.com/danielroe/nuxt-vitest) - testing in Nuxt. The
196+
package is under active development, so we should pin to the patch version
197+
`nuxt/i18n` - internationalization for Nuxt. Still in beta.
198+
199+
## Alternatives
200+
201+
<!-- Describe any alternatives considered and why they were not chosen or recommended. -->
202+
203+
Migrate to a non-Nuxt SSR solution for Vue. This would require significant
204+
changes to code for an unclear benefit.
205+
206+
## Design
207+
208+
<!-- Note any design requirements for this plan. -->
209+
210+
The designs should stay exactly the same.
211+
212+
## Parallelizable streams
213+
214+
<!-- What, if any, work within this plan can be parallelized? -->
215+
216+
The Nuxt 2 changes can be worked on immediately. The changes to Nuxt 3 branch
217+
can be parallellized after the initial PR.
218+
219+
## Blockers
220+
221+
<!-- What hard blockers exist which might prevent further work on this project? -->
222+
223+
## Accessibility
224+
225+
<!-- Are there specific accessibility concerns relevant to this plan? Do you expect new UI elements that would need particular care to ensure they're implemented in an accessible way? Consider also low-spec device and slow internet accessibility, if relevant. -->
226+
227+
## Rollback
228+
229+
<!-- How do we roll back this solution in the event of failure? Are there any steps that can not easily be rolled back? -->
230+
231+
## Privacy
232+
233+
<!-- How does this approach protect users' privacy? -->
234+
235+
## Localization
236+
237+
<!-- Any translation or regional requirements? Any differing legal requirements based on user location? -->
238+
239+
## Risks
240+
241+
<!-- What risks are we taking with this solution? Are there risks that once taken can’t be undone?-->
242+
243+
## Prior art
244+
245+
<!-- Include links to documents and resources that you used when coming up with your solution. Credit people who have contributed to the solution that you wish to acknowledge. -->

0 commit comments

Comments
 (0)