Page MenuHomePhabricator

Pinia ResourceLoader module does not implement vue-demi's functions
Closed, ResolvedPublic2 Estimated Story PointsBUG REPORT


Steps to replicate the issue (include links if applicable):

  • Import the pinia ResourceLoader module while in RL debug mode/having Vue development mode set
  • Start a vite (or others) dev server, e.g. using vite-plugin-mediawiki-userscript
  • Enable HMR (hot module reloading) and trigger a store reload

What happens?:
The pinia HMR acceptor errors:

Uncaught (in promise) TypeError: vueDemi.set is not a function
    createSetupStore load.php:1560
    useStore load.php:1836
    Pinia load.php:1228
    accept hmr.ts:77
    fetchUpdate hmr.ts:312
    queueUpdate hmr.ts:277
    queueUpdate hmr.ts:277
    handleMessage client.ts:205
    handleMessage client.ts:203
    setupWebSocket client.ts:91
    setupWebSocket client.ts:90
    <anonymous> client.ts:67

Line 1560 of resources/lib/pinia/pinia.iife.js:

vueDemi.set(hotState.value, key, vueDemi.toRef(setupStore, key));

The pinia attempts to call vueDemi.set, which does not exist because it is usually polyfilled by vue-demi. However, vue-demi is not actually loaded anywhere, and is just replaced with a require( 'vue' ) call by ResourceLoader (see resources/Resources.php in dc17d0e1e42827903b92032dafb8e2ff0800583a). This decision was made in T326174#8533382:

Thankfully, the iife build inlines @vue/devtools-api, and we can provide Vue 3 itself in vue-demi's place.

However, this neglects the usage of vue-demi specific functions set and del, which are used 4 and 3 times respectively in HMR functions (blocked by a DEV guard, and compiled out in .prod.js). There are also 5 usages of set in other parts of the code, but are all safely behind vueDemi.isVue2 (which actually doesn't exist, since it is usually set to false by vue-demi, but evaluates to falsy) checks. This means that no production code is affected by this.

What should have happened instead?:
ResourceLoader inlines/adds the vue-demi module (only 559 bytes unminified, vueuse/vue-demi/lib/v3/index.cjs) to pinia's RL module. This only needs to happen when the dev version of pinia is loaded (i.e., $config->get( MainConfigNames::VueDevelopmentMode ) || $context->getDebug()).

Fixing this would really help the developer experience of using the Vue stack for writing a MW userscript/gadget.

Software version (on Special:Version page; skip for WMF-hosted wikis like Wikipedia):
Other information (browser name/version, screenshots, etc.):

Event Timeline

Sportzpikachu renamed this task from Pinia ResourceLoader module does not implement `vue-demi`'s functions to Pinia ResourceLoader module does not implement vue-demi's functions.May 9 2024, 11:43 AM


  1. Add P62264 to your common.js
  2. Create a test page with <div id="app"></div>
  3. Load the test page with ?debug=2 to load the dev version of pinia
  4. Use the counter and observe the state updating correctly
  5. Use the "Trigger HMR" button to simulate a hot module reload
  6. Observe the error in the console

What should happen instead:

  1. Uncomment lines 5-21 in the common.js to provide the vue-demi functions
  2. Reload the test page (ensure ?debug=2 is still set), use the counter, and trigger HMR
  3. Observe that no error is thrown from pinia, and the counter state is kept
  4. Use the counter, and it should increment by 2s instead of 1s, due to the store module being swapped

Change #1029981 had a related patch set uploaded (by Sportzpikachu; author: Sportzpikachu):

[mediawiki/core@master] pinia: add vue-demi module to fix dev mode HMR

CCiufo-WMF subscribed.

Thanks for filing this issue @Sportzpikachu. Design-System-Team will try to review this task and your patch some time next week.

Catrope set the point value for this task to 2.May 13 2024, 6:04 PM

Thank you for finding this bug and fixing it!

vite-plugin-mediawiki-userscript is very cool BTW! We'll have to keep that in mind if/when we add Vue HMR support to MediaWiki itself.

Change #1029981 merged by jenkins-bot:

[mediawiki/core@master] pinia: add vue-demi module to fix dev mode HMR