davestewart / nuxt-content-assets

Enable locally-located assets in Nuxt Content
https://npmjs.com/package/nuxt-content-assets
108 stars 7 forks source link

Errors with `nuxi generate` #76

Closed davestewart closed 2 months ago

davestewart commented 2 months ago

Description

The playground site does not build via nuxi generate.

Most of the pages render, but there various document and image errors and the build fails:

Errors prerendering:
  ├─ /_ipx/q_50&blur_3&s_20x20/assets/images/sicilian-fish-stew.jpg (2ms)         nitro 11:36:02 AM
  │ ├── Error: [404] IPX_FILE_NOT_FOUND
  │ └── Linked from /assets/nuxt-image
  ├─ /_ipx/_/assets/images/sicilian-fish-stew.jpg (3ms)                           nitro 11:36:02 AM
  │ ├── Error: [404] IPX_FILE_NOT_FOUND
  │ └── Linked from /assets/nuxt-image
  ├─ /api/_content/query/4xSR5EkVao.1713263758322.json (0ms)                      nitro 11:36:02 AM
  │ ├── Error: [404] Document not found!
  │ └── Linked from /paths/sicilian-fish-stew
  ├─ /api/_content/query/UWXtQqG07Y.1713263758322.json (1ms)                      nitro 11:36:02 AM
  │ ├── Error: [404] Document not found!
  │ └── Linked from /paths/pesto-salmon-lentils
  ├─ /api/_content/query/AR7iJB1PK5.1713263758322.json (0ms)                      nitro 11:36:02 AM
  │ ├── Error: [404] Document not found!
  │ └── Linked from /paths/italian-bean-stew
                                                                                  nitro 11:36:02 AM

I don't know if it is these images particularly which are making the site fail, or if there is a problem with the pages, or links (the error message is not that clear).

Context

Looking at the physical file paths in output it seems that local images are being generated as documents (with folders, index.html and _payload.json files) and the actual images are not being copied directly into the .output structure:

CleanShot 2024-04-16 at 11 48 31

It seems that the way prerendering works (at least with content) has changed from earlier version as the images used to be copied from public directly into the output structure and the site would build fine:

CleanShot 2024-04-16 at 12 38 45

I've created a new branch (branched from 1.3.3 + a couple of fixes) to demo the site working previously:

git checkout temp/generate

Note that dev and build do not have this problem, as images are served directly from .nuxt/content-assets/public by NItro:

CleanShot 2024-04-16 at 11 47 18

Ideas to solve

Solutions

It might be that delegating all image generation to Nuxt Image might solve this, as Nuxt Image does copy the images from the public folder:

Triggers

To see if any particular files, links or images are causing this, I will remove all the content, and start adding it back slowly.

CleanShot 2024-04-16 at 12 09 02

Environment info

I recently updated the project (working versions last year were in the 1.3.x range) as Nuxt Image support needed improving, so I updated most of the packages in the module and playground to align with the current module builder version.

I need to confirm if this was a problem with previous versions of Nuxt; as of Nuxt 3.7 I'm pretty sure it worked as expected.

Node v20.11.1

nuxt-content-assets@1.4.2 /Volumes/Data/Work/OpenSource/JavaScript/NuxtContentAssets/nuxt-content-assets
├── @nuxt/content@2.12.1
└── nuxt@3.11.2
davestewart commented 2 months ago

Have narrowed down generate errors to 2 playground files, or when global Nuxt Image components are used:

Which is fortunate, as the rest (i.e. ones just using local paths!) seem fine.

Nuxt Image

Layer config

The .nuxt/content-assets layer only gets picked up every other generate:

Not picked up:

CleanShot 2024-04-16 at 13 35 36

Picked up:

CleanShot 2024-04-16 at 13 36 50

Note that at the start of the first run Nuxt has already complained that nuxt content assets cannot be extended from:

/usr/local/bin/npm run dev:generate

> nuxt-content-assets@1.4.2 dev:generate
> nuxi generate playground

Debugger listening on ws://127.0.0.1:62790/96d1844d-0edc-4f1c-b37e-bc429ac3bf91
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
Nuxt 3.11.2 with Nitro 2.9.6                                               2:13:02 PM
ℹ Using Nitro server preset: static                                       2:13:02 PM

[2:13:02 PM]  WARN  Cannot extend config from .nuxt/content-assets in /Volumes/Data/Work/OpenSource/JavaScript/NuxtContentAssets/nuxt-content-assets/playground

Then even though the layer folder is created, Nuxt has not created the layer, and Nuxt Image does not add it to the IPX folders:

CleanShot 2024-04-16 at 14 08 36

If generate is run again, the folder exists at the start, the layer file is picked up, then Nuxt Image works (unless global Nuxt Images are used and frontmatter is used somwhere in the site)

Frontmatter

IPX errors occur for any files which use frontmatter:

// playground/content/advanced/frontmatter/index.md
image: ./turkey-casserole.jpg?a=1&b=2

Suspect the path is not being transformed before prerendering.

It turns out the NCA imageSize config option breaks Nuxt Image as it's appended to the URL but Nuxt Image treats it as part of the URL and serialises it, breaking the final URL:

image.jpg%3Fwidth%3D200%26height%3D100

Summary

Cause

The reason why the playground blows up is most likely because:

I suspect the strange document-images shown above may be an artefact of Nuxt Image; perhaps Nitro thinks the paths are docs, even though they don't exist, so somehow renders them? I know that prerendering is achieved through walking the links in the files, so that kinda makes sense, especially if frontmatter has not been transformed properly (will probably drop debugs in to test when this is or isn't happening).

Workaround

The trick to getting generate working (and will update the docs) will be:

  1. if you can help it, don't use Nuxt Image
  2. if you do use Nuxt Image, use nuxi build
  3. if you have to use generate:
    • wait for a fix, or
    • run generate twice
    • switch to version 1.3.3 and configure accordingly

Also, not sure if we can use route rules to solve isolated cases or not.

Fix

Layers

As the config is read in and layers created before any hook are run, it seems that the .nuxt folder cannot be a suitable candidate for a layer, therefore:

+- node_modules
    +- nuxt-content-assets
        +- cache
            +- public
            |   +- ...
            +- nuxt.config.json

Frontmatter

Disable the imageSize setting, and all is good.