donnikitos / vite-plugin-php

Vite's speed and tooling to preprocess PHP-files!
https://www.npmjs.com/package/vite-plugin-php
MIT License
40 stars 0 forks source link

Uncaught TypeError #37

Closed theking2 closed 1 week ago

theking2 commented 1 week ago

I get an Uncaught TypeError:

index.php.js:10 Uncaught TypeError: Cannot read properties of null (reading 'dataset') at index.php.js:10:377613

vite.config.js contains:

    usePHP({
      entry: [
        'index.php',
      ]
    })

But I'm sure if the entry is really needed.

theking2 commented 1 week ago

Btw the input.php looks like

<?php declare(strict_types=1);
require 'inc/global.inc.php';
require 'inc/user-check.php';
?>
<!DOCTYPE html>
<html lang="de">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" type="image/svg+xml" href="/logo-nm.svg">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Materialverleih NM</title>
  </head>

  <body>
    <div
      id="app"
      data-fullname="<?=     $_SESSION['AD_user']      ?>"
      data-user-id="<?=      $_SESSION['user_id']      ?>"
      data-user-type-id="<?= $_SESSION['user_type_id'] ?>"
    >
    </div>

  </body>
</html>

it works wo vite-plugin-php if I replace the index.html with this file with theses two lines in the head:

    <script type="module" crossorigin src="/assets/index.js"></script>
    <link rel="stylesheet" crossorigin href="/assets/index.css">
donnikitos commented 1 week ago

Hi @theking2, looks like your /assets/index.js contains an error. The object from which you try to access dataset does not exist. As I suspect you are trying to access the data properties from div#app, right? Since the file loads asynchronously (maybe even before the DOM) you will need to run the function on load, with something like this:

window.addEventListener('load', (event) => {
  const element = document.getElementById('app');

  console.log(element?.dataset);
});

⚠️ Attention, this is not plugin-specific, this is how JS-modules work.

Another option would be to put <script type="module" crossorigin src="/assets/index.js"></script> at the end of the file, just before </body>. See the example in the starter repository.

theking2 commented 1 week ago

Thanks. I understand the requirement of the DOM being loaded. But I don't how vite-plugin-php is helping me. What I currently do.

Do I understand the vite-plugin-php correctly that I no longer need the index.html in the root and replace it with my index.php from /public?

donnikitos commented 1 week ago

Yes, exactly you do not need a separate /public/index.php anymore. Now instead of the /index.html you can have a /index.php and have your Vue app started from there.

theking2 commented 1 week ago

thanks again.

this index.php in /

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <link rel="icon" type="image/svg+xml" href="/logo-nm.svg">
  <script type="module" src="/src/main.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Materialverleih NM</title>
</head>

<body>

  <div
    id="app"
    data-fullname="<?= $_SESSION['AD_user'] ?>"
    data-user-id="<?= $_SESSION['user_id'] ?>"
    data-user-type-id="<?= $_SESSION['user_type_id'] ?>">
  </div>

</body>

</html>

after run build is turned into this in /dist

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <link rel="icon" type="image/svg+xml" href="/logo-nm.svg">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Materialverleih NM</title>
  <script type="module" crossorigin src="/assets/index.php.js"></script>
  <link rel="modulepreload" crossorigin href="/assets/VueStuff.js">
  <link rel="stylesheet" crossorigin href="/assets/index.css">
</head>

<body>

  <div
    id="app"
    data-fullname="<?= $_SESSION['AD_user'] ?>"
    data-user-id="<?= $_SESSION['user_id'] ?>"
    data-user-type-id="<?= $_SESSION['user_type_id'] ?>">
  </div>

</body>

</html>

Is that correct behaviour?

donnikitos commented 1 week ago

This looks correct, but I would suggest you to modify your /index.php a little:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <link rel="icon" type="image/svg+xml" href="/logo-nm.svg">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Materialverleih NM</title>
</head>

<body>

  <div
    id="app"
    data-fullname="<?= $_SESSION['AD_user'] ?>"
    data-user-id="<?= $_SESSION['user_id'] ?>"
    data-user-type-id="<?= $_SESSION['user_type_id'] ?>">
  </div>

  <script type="module" src="/src/main.js"></script>

</body>

</html>

Like in the base example of Vue: https://github.com/vuejs/create-vue/blob/main/template/base/index.html This will make sure, that your app will get mounted properly.