idleberg / php-wordpress-vite-assets

Injects assets from a Vite manifest to the Wordpress head, supports themes and plugins
https://packagist.org/packages/idleberg/wordpress-vite-assets
MIT License
130 stars 12 forks source link

Failed loading manifest: TypeError: Typed property #2

Closed carljustineoyales closed 2 years ago

carljustineoyales commented 2 years ago

Description

Getting this TypeError when I copied the code in the README file

Here's the error

Fatal error: Uncaught Exception: Failed loading manifest: TypeError: Typed property Idleberg\ViteManifest\ViteManifest::$manifest must be string, array used in <wordpress theme dir>\vendor\idleberg\vite-manifest\src\ViteManifest.php:42

Steps to Reproduce

  1. Copy the README code to an existing WordPress code
  2. WP running on PHP Version 7.4

Expected behavior:

should proceed without errors

Actual behavior:

got typed error

Versions

PHP: all

idleberg commented 2 years ago

Looks like I misplaced the baseUrl in the example, could you please try again using the updated example code?

carljustineoyales commented 2 years ago

used the updated code but still gave me the same error message. I think it is something to do with the ViteManifest.php line 42?

idleberg commented 2 years ago

Could you please give v0.4.1 a try, I think I found the problem

carljustineoyales commented 2 years ago

I updated the plugin to v0.4.1 and I used the code from the README

$baseUrl = get_stylesheet_directory();
$manifest = $baseUrl . "/manifest.json";
$entryPoint = "index.ts";

$viteAssets = new WordpressViteAssets($manifest, $baseUrl);
$viteAssets->addAction($entryPoint);

it produces a different error, here's the full error message

Fatal error: Uncaught TypeError: Return value of Idleberg\ViteManifest\ViteManifest::getEntrypoint() must be of the type array, null returned in C:\Users\cjoyales\Desktop\Work\fujimotoyoshitaka\dev\wordpress+vite\wp-content\themes\vite-image-grid\vendor\idleberg\vite-manifest\src\ViteManifest.php:78 Stack trace: #0 C:\Users\cjoyales\Desktop\Work\fujimotoyoshitaka\dev\wordpress+vite\wp-content\themes\vite-image-grid\vendor\idleberg\wordpress-vite-assets\src\WordpressViteAssets.php(87): Idleberg\ViteManifest\ViteManifest->getEntrypoint('vite/vite-proje...') #1 C:\Users\cjoyales\Desktop\Work\fujimotoyoshitaka\dev\wordpress+vite\wp-content\themes\vite-image-grid\vendor\idleberg\wordpress-vite-assets\src\WordpressViteAssets.php(54): Idleberg\WordpressViteAssets\WordpressViteAssets->getScriptTag('vite/vite-proje...') #2 C:\Users\cjoyales\Desktop\Work\fujimotoyoshitaka\dev\wordpress+vite\wp-includes\class-wp-hook.php(307): Idleberg\WordpressViteAssets\WordpressViteAssets->Idleberg\WordpressViteAssets{closure}('') #3 C:\Users\cj in C:\Users\cjoyales\Desktop\Work\fujimotoyoshitaka\dev\wordpress+vite\wp-content\themes\vite-image-grid\vendor\idleberg\vite-manifest\src\ViteManifest.php on line 78

carljustineoyales commented 2 years ago

i changed the

$entryPoint = "index.ts";

to

$entryPoint = "index.html";

because on the ViteManifest.php you have $this->manifest[$entrypoint], I dont usually work with PHP that often so it is just a guest, it worked but it gave me some warnings about the file_get_contents() it doesn't seem to find index.js,vendor.js, and style.css

Edit:

I forgot to set the build.ssr on the vite config to true

$entryPoint = "src/main.js";
carljustineoyales commented 2 years ago

I think this is a ViteManifest issue. the return UriResolver::resolve($relativeUri, $baseUri); on the getPath() function returns the themes directory of wordpress instead of the current project-directory

uriresolver output

/wp-content/themes/assets/main.dce1f30e.js

but I think it should be

/wp-content/themes/<project-directory>/assets/main.dce1f30e.js
idleberg commented 2 years ago

it produces a different error, here's the full error message

I haven't worked on PHP projects since it introduces type declarations, so I'm still learning. Hope we can resolve those issues soon.

$entryPoint = "index.html";

While I'm not aware of all the possibilities that Vite offers, I don't think the entrypoint can or should be an HTML file. Certainly not when working with SvelteKit. I might be wrong, of course, but in that case I would love to take a look at such a manifest.

I think this is a ViteManifest issue. the return UriResolver::resolve($relativeUri, $baseUri); on the getPath() function returns the themes directory of wordpress instead of the current project-directory

You can put whatever suits your needs as the baseUri. I wanted to use a practical example, but maybe it only works for the mindset in which I created this library.

k1sul1 commented 2 years ago

I couldn't get this to work either, so I did it myself. I didn't bother with generating sha hashes, it's not a feature that I need or even want, and it's bad for performance, IMO the hashes should be postprocessed into the manifest at build time, not with PHP at runtime.

I put my work in a "batteries included" empty theme repository, for easy use, if anyone happens to stumble upon this issue and is looking for solutions, that might help.

https://github.com/k1sul1/wp-theme-with-vite

// functions.php
add_action('wp_enqueue_scripts', function() use ($app, $localizeData) {
  $build = $app->manifests['vite'];

  $handles = $build->enqueue('src/client.tsx', ['react']);
  wp_localize_script($handles[0], 'wptheme', $localizeData);
});
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
import { resolve, basename } from "path"

const themeFolder = basename(__dirname)

// https://vitejs.dev/config/
export default defineConfig({
  server: {
    port: 8888,
    origin: "http://localhost:8888",
  },
  plugins: [react()],

  base: `/wp-content/themes/${themeFolder}/dist/`,

  build: {
    manifest: true,
    minify: false,
    target: "es2015",
    rollupOptions: {
      input: {
        client: resolve(__dirname, "src/client.tsx"),
        admin: resolve(__dirname, "src/admin.tsx"),
      },
    },
  },
})
// header.php
<?php
    if ($app->manifests['vite']->isDev()) { ?>
    <script type="module" src="http://localhost:8888/@vite/client"></script>
    <script type="module">
      import RefreshRuntime from 'http://localhost:8888/@react-refresh'
      RefreshRuntime.injectIntoGlobalHook(window)
      window.$RefreshReg$ = () => {}
      window.$RefreshSig$ = () => (type) => type
      window.__vite_plugin_react_preamble_installed__ = true
    </script>
<?php

https://github.com/k1sul1/wp-theme-with-vite/blob/master/classes/class.vite.php

idleberg commented 2 years ago

I'm sure you posted your comment in good spirit, but please stay on-topic. I'm interested in more insights, so I can reproduce your issues with this package. What helps are real-world examples of your manifests or Minimal, Reproducible Examples (MRE).

The other thing I take from your comment is that I might add an option to toggle support for hashes.

k1sul1 commented 2 years ago

I saw this repository on https://github.com/vitejs/awesome-vite#integrations-with-backends, found out it doesn't work and needed a solution instantly. I browsed through the repositories and this issue, and when there wasn't a solution other than patching it myself, I decided that I'd rather write my own code for such a simple matter. When it worked, I figured I might save someone else the few hours I spent on this problem.

That was faster than begging for help in a month old issue, esp. when I didn't want to use a 3rd party package in the first place. My manifest is in the same format as the one listed here, so there's nothing unusual about it. My repo should work as a MRE, just add your package and replace my enqueue with yours. I can back this statement:

I think this is a ViteManifest issue. the return UriResolver::resolve($relativeUri, $baseUri); on the getPath() function returns the themes directory of wordpress instead of the current project-directory

I had the same issue. I have zero tolerance for path related issues in WordPress. I've dealt with them for 10 years in my own code, I'm not going to debug those in libraries that I've never even heard of before.

My solution just parses the manifest and provides a tiny abstraction to enqueue the CSS and JS.

danimalweb commented 2 years ago

I also have the same issue as:

I think this is a ViteManifest issue. the return UriResolver::resolve($relativeUri, $baseUri); on the getPath() function returns the themes directory of wordpress instead of the current project-directory

Any easy update to resolve this? I'm sure I'm passing in my paths correctly and traced it down to getPath not returning my expected final path.

danimalweb commented 2 years ago

In addition to the above, I have a space in my base path /Users/daniel/Local Sites/tofino/app/public/wp-content/themes/tofino that is being resolved as /Users/daniel/Local%20Sites/tofino/app/public/wp-content/themes/tofino which is preventing file_get_contents from working I think.

idleberg commented 2 years ago

I haven't had the time yet to deep-dive into this, but it's my suspicion that the example given in the README.md causes confusion over the correct usage of this package (my bad!).

When instantiating the class, two parameters are passed:

  1. the first argument needs to an absolute path to manifest.json
  2. the second argument should be an URL, so the assets can be resolved correctly in the client

For the tests, a local path should work as a second argument, but that shouldn't be relevant for most people.

github-actions[bot] commented 2 years ago

This issue was closed because it has been stalled for 14 days with no activity.