richardtallent / vite-plugin-singlefile

Vite plugin for inlining JavaScript and CSS resources
MIT License
808 stars 53 forks source link

defineExpose() function does not work after rollup #78

Closed mbcbus closed 9 months ago

mbcbus commented 1 year ago

I have a use case where I'm trying to compile a single file where a window level function can update data in a rendered Vue app. While I am able to get this working using the defineExposed() function in Vue3/Composition API locally via npm run dev, after I compile with npm run build the same working function now returns an error:

Uncaught TypeError: Cannot read properties of null (reading 'exposed')
    at logTest (index.html:41:23)
    at HTMLButtonElement.onclick (index.html:56:49)

It appears that the defineExposed() function is not compatible with the rollup, but I'm not super familiar with vue or this plugin so I'm having trouble trying to troubleshoot.

Basic test code is as follows:

Index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test App</title>
    <script>
      function logTest(newData) {
        // eventually newData will be a passed JSON object
        var item = {
          "name": "TEST NEW ROW 1",
          "regions": []
        }
        var item2 = {
          "name": "TEST NEW ROW 2",
          "regions": []
        }
        var update = {
          "labelRows": [item, item2]
        };
        app._instance.exposed.logTest(update);
      }
    </script>
  </head>
  <body class="m-0 p-0">
    <div id="app" class="w-full"></div>
    <script type="module" src="/src/main.ts"></script>
    <button onclick="logTest('This is a test')">TEST UPDATE</button>
  </body>
</html>

main.ts

import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
window.app = app;
app.mount('#app')

App.vue

<script setup lang="ts">
  import { ref } from 'vue'
  import data from './assets/defaultData.json'

  const tableData = ref(data)

  function logTest (newData) {
    console.log("Test Reactivity Function");
    alert(newData);
    tableData.value = newData;
  }

  defineExpose({
    logTest
  })
</script>

<template>
  <div class="px-4">
    <table class="w-full">
      <tr v-for="row in tableData.rows">
         loop code here
      </tr>
    </table>
  </div>
  <h1>TEST VALUE: {{ tableData }}</h1>
</template>
richardtallent commented 1 year ago

Hi, this plugin is for rollup, but I can't help with issues related to rollup itself, only the actions this plugin performs. Does this problem exhibit when you do not use this specific plugin?

FWIW, I would suggest using Mitt or some other solution for passing messages between a window-level script and Vue components rather than calling into private members of app.