nititech / php-vite-starter

A modern vanilla PHP-Vite starter repo, utilizing vite-plugin-php
https://github.com/nititech/php-vite-starter
MIT License
18 stars 1 forks source link

A couple of build issues #2

Closed NicolasReibnitz closed 3 months ago

NicolasReibnitz commented 3 months ago

Hi!

🚀 First of all, thank you for this comprehensive starter pack! 🚀

It could become my go-to setup when working with PHP sites!

I do have a couple of problems, though. They might all be related to my limited knowledge of PHP and Apache, though.

However, simply cloning the repo, installing the dependencies for node and PHP, and running npm run build (without touching anything) produces a dist folder that does not seem to work in any environment I could test. I think I know why, but again, I might just have missed something.

Putting the content of the dist folder in an Apache environment doesn't seem to work, and here is where it gets interesting...


1. system/main.php can't be found

This is ironic because it would set the necessary include_path. 😄

This results in the following error:

Warning: require(system/main.php): Failed to open stream: No such file or directory in /opt/homebrew/var/www/test/pages/index.php on line 4

Fatal error: Uncaught Error: Failed opening required 'system/main.php' (include_path='.:/opt/homebrew/Cellar/php/8.3.9/share/php/pear') in /opt/homebrew/var/www/test/pages/index.php:4 Stack trace: #0 {main} thrown in /opt/homebrew/var/www/test/pages/index.php on line 4

Changing the require to ../system/main.php would work, but I might be missing something.


2. The compiled .js files are inserted at the beginning of the built PHP files...

and reference elements that aren't on the page yet. So, the whole getElementById approach crashes the page.

As an example, pages/index.php

<?php
require('system/main.php');

$layout = new HTML(title: 'PHP via Vite');
?>

<div class="flex flex-col items-center gap-10 text-2xl">
  <?php include('partials/nav.php'); ?>

  <div class="flex flex-col items-center">
    <?php include('partials/vite-name.php'); ?>

    <div>+</div>

    <img src="/logo.svg" class="w-20" />
  </div>

  <div id="repos" class="text-base flex gap-10"></div>
</div>

<script src="/src/scripts/repos.ts" type="module"></script>

gets compiled to

<script type="module" crossorigin src="/public/index.php-DlZYXcJR.js"></script>
<link rel="modulepreload" crossorigin href="/public/modulepreload-polyfill-B5Qt9EMX.js">
<?php
require('system/main.php');

$layout = new HTML(title: 'PHP via Vite');
?>

<div class="flex flex-col items-center gap-10 text-2xl">
  <?php include('partials/nav.php'); ?>

  <div class="flex flex-col items-center">
    <?php include('partials/vite-name.php'); ?>

    <div>+</div>

    <img src="/logo.svg" class="w-20" />
  </div>

  <div id="repos" class="text-base flex gap-10"></div>
</div>

and index.php-DlZYXcJR.js starts with const t=document.querySelector("#repos"), with #repos not existing at this point.


I'm not sure why the scripts get inserted at the beginning of the build files while they are at the end of the source files or what to do about that.

Moving

<script type="module" crossorigin src="/public/index.php-DlZYXcJR.js"></script>
<link rel="modulepreload" crossorigin href="/public/modulepreload-polyfill-B5Qt9EMX.js">

manually to the end and changing require('system/main.php'); to require('../system/main.php'); in all the PHP files fixes those two problems, and the site seems to work fine.


As a side note, I assume you haven't set this up to use vite preview, as this isn't a script in package.json and uses the basepath pages by default. Anything is only available using pages twice in the URL, for example, http://localhost:4173/pages/pages/index.php. Running npx vite preview --base / fixes that problem, but the .htaccess file obviously doesn't work this way either.

Changing vite.config.js from

export default defineConfig(({ command }) => {
  const base = command === 'serve' ? '/pages/' : '/';
  // ...

to

export default defineConfig(({ command, mode }) => {
  const base = mode === 'development' ? '/pages/' : '/';
  // ...

fixes the basepath problem for vite preview. I'm unsure if the new rewriteUrl function would deal with the missing support for .htaccess. I don't think it could, but that's not really important anyway.


My setup: Node: v18.20.3 PHP: v8.3.9

Thanks in advance!

Cheers, Nicolas

verhulstd commented 3 months ago

thx for your post here. Facing the same issues on windows here...

donnikitos commented 3 months ago

Hi @NicolasReibnitz,

I am glad, that you you like our PHP starter repository that much! Our goal is to become something like Astro, but for PHP 😉


1. system/main.php can't be found

No worries you did nothing wrong in your testing setup - unfortunately we didn't test the build in a local, nested environment... And this is also where the problem was: Our first assumption was, that whenever you deploy the dist folder usually the domain points to the root (where the .htaccess lives) und the scripts are executed solely from there. Now this issue should be resolved with #3.

2. The compiled .js files are inserted at the beginning of the built PHP files...

This seems to be a known thing in Vite, see this discussion. Apparently <script type="module" /> defer by default, hence they execute after all the DOM is parsed, but before the DOMContentLoaded event. See also mdn web docs:

3. vite preview, vite build --watch, etc...

Yeah, those functions are not build in yet... They technically should be available, but since vite-plugin-php is a one-man-open-source-project for now, there was not enough time to get it to work 🤷🏼‍♂️ If the community and the need grows they obviously will be available 😉

Also a small note: for that functionality the issue should be opened in the vite-plugin-php repository.

Cheers, Nikita

NicolasReibnitz commented 3 months ago

Hi, @donnikitos!

Thanks for your quick response, and excuse my delayed response! 😄 I was swamped last week and have only returned to this project.

1. system/main.php can't be found

This works as expected on my local Apache server but not my shared hosting web server. I assume that's because mod_php.c isn't available there.

But the .htaccess file inspired me to what eventually fixed the issue for me: I added a php.ini file to the pages directory containing the line include_path=".:../". This works for me instead!

2. The compiled .js files are inserted at the beginning of the built PHP files...

Yes, you are correct. The problem was system/main.php not being found, not with the DOM not being loaded. Fixing this issue eliminates the problem of the #repos element not being available.

3. vite preview, vite build --watch, etc...

Yeah, I figured as much. I only mentioned it as a side note.


Well, I think I found a complete working setup now! I also added Vue to the thing, which is working now as well. I guess I can now start with the actual project I was planning. 😄 But putting the time in to get this working was well worth it!

I wonder if I can even use this in my legacy Laravel project that doesn't support Vite with Mix yet. 🤔 Does it work with Laravel?

Anyway, thanks for your support, and I'll let you know if something else comes up!

Cheers, Nicolas

donnikitos commented 3 months ago

No worries @NicolasReibnitz, fully understand you 😉

Interesting... In that case... I am actually considering to transition the starter from a file based router to a centralized routing system with one entry file and programmatically calculated routes. With that come a few benefits like slightly better maintainable and more modular code. Also that would help with the include path definitions and stuff.

In theory you should be able to start your legacy Laravel project, but you might need to get your hands pretty dirty 😅 I unfortunately not that familiar with Laravel and won't be of much help...