fresh icon indicating copy to clipboard operation
fresh copied to clipboard

Outdated docs for Docker and/or with DaisyUI.

Open FuncProgLinux opened this issue 5 months ago โ€ข 6 comments

I fell for the clickbait lies today while working on my project, the CLI said that apparently there's a new Fresh version out, so I blindly followed the migration guide just to realize I was practically live testing an alpha or pre-alpha, not a 2.X stable release after reading the main site header while exiting the Docs :/

I would like to know if forcing non-ready products upon the users is a policy or something. Or if it's possible to retire the "upgrade now!" CLI message because it's clearly misleading. If it's a beta then everything is a beta, if it's a stable release, then everything should be stable, gray lines are misleading at best and dangerous at worst on software.

I know this is easily fixable by git revert / git checkout but why say it's a new stable version when it's obviously not past the alpha phase? ๐Ÿคจ

TL;DR

  • DaisyUI instructions are wrong, kill pipelines due to type errors
  • Docker instructions are wrong, Fresh generates toy .mjs files not able to run
  • Versioning & readiness is misleading to users.

Things already tried

  • Deleting node_modules and deno.lock, then running deno install -r --allow-scripts
  • Changing nodeModulesDir from auto to manual
  • Using a new project base
  • Running deno task update
  • Cleaned docker images with docker image prune -af and started from fresh
  • Excluded/Included deno.lock in .dockerignore (neither worked)

On Docker

The Docker instructions don't work either, this is the original dockerfile proposed by the docs:

FROM denoland/deno:latest

ARG GIT_REVISION
ENV DENO_DEPLOYMENT_ID=${GIT_REVISION}

WORKDIR /app

COPY . .
RUN deno task build
RUN deno cache _fresh/server.js

EXPOSE 8000

CMD ["serve", "-A", "_fresh/server.js"]

This is my variation

FROM docker.io/denoland/deno:alpine-2.5.2

ARG GIT_REVISION
ENV DENO_DEPLOYMENT_ID=${GIT_REVISION}

WORKDIR /app

COPY . .

RUN deno install --allow-scripts
RUN deno task build
RUN deno cache _fresh/server.js

EXPOSE 8000

ENV TERM=xterm-256color
ENV DENO_NO_UPDATE_CHECK=disable

CMD ["serve", "-A", "--unsafely-ignore-certificate-errors", "_fresh/server.js"]

I had to add deno install as a step or otherwise it won't find vite unless you add node_modules/ to the OCI image. Which is a big no in most scenarios.

Then I had to deno install --allow-scripts because Deno won't shut up about needing deno install --allow-scripts=npm:@tailwindcss/oxide otherwise the precious yet-another-rust-tool plugin won't work.

In the end neither worked. If you try to create a container either with Docker CLI or with Compose you'll get the following error:

DANGER: TLS certificate validation is disabled for all hostnames
error: Uncaught (in promise) TypeError: Cannot assign to read only property 'cli' of object '#<Object>'
_default$1h.cli = _cli$1;
                ^
    at file:///app/_fresh/server/server-entry.mjs:9777:17
exit code: 1

What cli? There's no single cli import on this project. Is it the server CLI? Then why is that not in the docs? Am I expected to include the TypeScript types for a CLI?

On DaisyUI

The template places the styles.css file inside an assets/ directory. But the documentation example uses the same old static/styles.css approach. What is the "new" way then? It's either one on all cases or the other on all cases but not the two ๐Ÿ™ƒ.

Importing it and adding it to the CSS just kills deno task check:

deno task check
Task check deno fmt --check && deno lint && deno check
Checked 133 files
Checked 93 files
error: Failed resolving types. [ERR_TYPES_NOT_FOUND] Could not find types for 'file:///home/fplinux/Desktop/project/node_modules/.deno/[email protected]/node_modules/daisyui/index.js' imported from 'file:///home/fplinux/Desktop/project/tailwind.config.ts'
   at file:///home/fplinux/Desktop/project/tailwind.config.ts:2:21

This would most likely kill pipeline processes if those are valuable to anyone (or if they even know those exist).

FuncProgLinux avatar Sep 27 '25 04:09 FuncProgLinux

Update, running locally does the exact same error:

deno task start
Task start deno serve -A _fresh/server.js
error: Uncaught (in promise) TypeError: Cannot assign to read only property 'cli' of object '#<Object>'
_default$1h.cli = _cli$1;
                ^
    at file:///home/fplinux/Desktop/project/_fresh/server/server-entry.mjs:9777:17

Doing deno task dev which is vite on the new template:

deno task dev
Task dev vite

  VITE v7.1.6  ready in 606 ms

  โžœ  Local:   http://127.0.0.1:5173/
  โžœ  Network: use --host to expose
  โžœ  press h + enter to show help
11:01:18 p.m. [vite] (ssr) Error when evaluating SSR module fresh:server_entry: Cannot assign to read only property 'cli' of object '#<Object>'
      at eval (/home/fplinux/Desktop/project/node_modules/.deno/[email protected]/node_modules/triple-beam/config/index.js:25:195)

Again...what cli is this so call update babbling about? Is this some kind of very late April Fools joke I ran into? ._.

FuncProgLinux avatar Sep 27 '25 05:09 FuncProgLinux

For a working, not trivial (but still a bit silly) Fresh 2 app using DaisyUI and Docker (Podman) to deploy to a local home server, please take a look here -> https://github.com/fry69/orw (the Fresh 2 app is inside the packages/frontend folder).

Notable things to look out for:

  • The app uses caddy as a reverse proxy to serve TLS with automatic Let's Encrypt certificates, this is not shown in this repository, but is almost trivial to implement
  • Using nodeModulesDir set to manual became a necessity since there is a bug in Deno, which prevents building the image with Podman on my local Ubuntu server when set to auto
  • This resulted in a few npm packages not finding their types automatically anymore, those needed to get added manually to the import section in deno.json
  • A deno install step is now mandatory as Deno no longer resolves/populates the node_modules folder automatically
  • This is annoying, but it has the great upside that it works

Otherwise it would help if you could either give a link to your source code repository or produce a small reproduction repository where you showcase your problems.

Fresh 2 is still a bit fresh, the shift to Vite has introduced some complications with packages which use CommonJS quirks. Ironing those out is currently an (unofficial) mission goal. If you spot packages that refuse to work with Fresh 2, please file an issue, that helps!

This error looks very much like a missing deno install step:

error: Failed resolving types. [ERR_TYPES_NOT_FOUND] Could not find types for
'file:///home/fplinux/Desktop/project/node_modules/.deno/[email protected]/node_modules/daisyui/index.js'
imported from 'file:///home/fplinux/Desktop/project/tailwind.config.ts'
  at file:///home/fplinux/Desktop/project/tailwind.config.ts:2:21

DaisyUI works fine in my silly app using 5.1.24

Update: After thinking about adding a monorepo section to the Fresh docs, it seems that this would be redundant. All relevant points can be found in the Deno docs -> https://docs.deno.com/runtime/fundamentals/workspaces/

fry69 avatar Sep 27 '25 05:09 fry69

* Using `nodeModulesDir` set to `manual` became a necessity since there is a bug in Deno, which prevents building the image with Podman on my local Ubuntu server when set to `auto`

I noticed this while running a Deno test suite that creates mock files using the jsr:@std/fs package. I thought It was the JSR package at first since the bare filesystem calls did yield results. Looking at other implementations is there a scenario where you wouldn't want a node_modules directory other than serverless platforms? It could be a great deal of help if this was the default for most common projects.

* A `deno install` step is now mandatory as Deno no longer resolves/populates the `node_modules` folder automatically

* This is annoying, but it has the great upside that it works

I also noticed this since the introduction of the install subcommands, I think this is the way to go, though, I don't know why scripts are not allowed by default on TailwindCSS if it so desperately needs it's rust plugin for CSS.

Otherwise it would help if you could either give a link to your source code repository or produce a small reproduction repository where you showcase your problems. Fresh 2 is still a bit fresh, the shift to Vite has introduced some complications with packages which use CommonJS quirks. Ironing those out is currently an (unofficial) mission goal. If you spot packages that refuse to work with Fresh 2, please file an issue, that helps!

The minimal reproducible error is the official template with any of the following commonJS packages:

  • mongoose or mongo
  • winston
  • moment (I know, I know ๐Ÿ˜–)

This error looks very much like a missing deno install step:

error: Failed resolving types. [ERR_TYPES_NOT_FOUND] Could not find types for
'file:///home/fplinux/Desktop/project/node_modules/.deno/[email protected]/node_modules/daisyui/index.js'
imported from 'file:///home/fplinux/Desktop/project/tailwind.config.ts'
  at file:///home/fplinux/Desktop/project/tailwind.config.ts:2:21

DaisyUI works fine in my silly app using 5.1.24

I'm installing using deno install -r --allow-scripts but the error is still there.

Update: After thinking about adding a monorepo section to the Fresh docs, it seems that this would be redundant. All relevant points can be found in the Deno docs -> https://docs.deno.com/runtime/fundamentals/workspaces/

I'm not using monorepos. It's a single fresh project ๐Ÿค”

FuncProgLinux avatar Sep 27 '25 18:09 FuncProgLinux

EDIT: I was absolutely wrong about this, I've edited this response to avoid misinforming users with my complains.

EDIT 1: These routes will work only in your frontend-only islands, the correct source of information for this is: https://fresh.deno.dev/docs/concepts/islands#rendering-islands-on-client-only

Adding a bit more sugar to the cake here. Local API handlers are either work differently than Fresh 1:

We assume a /routes/api/v1/products.ts file exists with a GET and a POST handler.

Given a route:

routes/example/shop.tsx:

import { define, State } from "$ui/utils";
import { Context, HttpError } from "fresh";

// Other imports ...

export const handler = define.handlers({
    async GET(_ctx: Context<State>) {
        const res: ShopProducts = await fetch(`/api/v1/products`).then(
            (res: Response): Promise<ShopProducts> => res.json(),
            (err: Error) => {
                console.error(`Failed to fetch  with error: ${err.message}`);
                throw new HttpError(500, `Error fetching products: ${err.message}`);
            }
        );
        return { data: { products: res.products } };
    },
});

export default define.page<typeof handler>(function ShopPage(props) {
    return (
        <main>
            <section>
                <div>
                    <FormTitle text="Fresh2 Test" />
                    <form
                        method="post"
                        action="/api/v1/products">
                        <label>
                            <FormLabel text="Choose a product" />
                            <select
                                name="invoice-for-product">
                                <option disabled selected>
                                    Choose a product from the list.
                                </option>
                                {props.data.products?.map((product: Product) => (
                                    <option value={product.name}>
                                        {product.name}
                                    </option>
                                ))}
                            </select>
                        </label>
                        <button type="submit">
                            Submit test
                        </button>
                    </form>
                </div>
            </section>
        </main>
    );
});

This also happens if one were to move the GET logic inside the page component itself:

export default define.page<typeof handler>(async function ShopPage(_ctx) {
    const data: ShopProducts = await fetch(`/api/v1/products`).then((res: Response): Promise<ShopProducts> => res.json)

    return (
        <main>
            <section>
                <div>
                    <FormTitle text="Fresh2 Test" />
                    <form
                        method="post"
                        action="/api/v1/products">
                        <label>
                            <FormLabel text="Choose a product" />
                            <select
                                name="invoice-for-product">
                                <option disabled selected>
                                    Choose a product from the list.
                                </option>
                                {props.data.products?.map((product: Product) => (
                                    <option value={product.name}>
                                        {product.name}
                                    </option>
                                ))}
                            </select>
                        </label>
                        <button type="submit">
                            Submit test
                        </button>
                    </form>
                </div>
            </section>
        </main>
    );
});

Both scenarios yield the following error on de Deno side:

Invalid URL: '/api/v1/products'

FuncProgLinux avatar Sep 27 '25 21:09 FuncProgLinux

Can you elaborate a bit on that? I'm getting the same error with plain Deno without Fresh.

// main.ts
const res = await fetch(`/api/v1/products`);
$ deno run -A main.ts
error: Uncaught (in promise) TypeError: Invalid URL: '/api/v1/products'
await fetch(`/api/v1/products`);
      ^
    at getSerialization (ext:deno_url/00_url.js:98:11)
    at new URL (ext:deno_url/00_url.js:405:27)
    at new Request (ext:deno_fetch/23_request.js:344:25)
    at ext:deno_fetch/26_fetch.js:374:29
    at new Promise (<anonymous>)
    at fetch (ext:deno_fetch/26_fetch.js:370:20)

marvinhagemeister avatar Sep 27 '25 23:09 marvinhagemeister

Can you elaborate a bit on that? I'm getting the same error with plain Deno without Fresh.

I was wrong about that and I've edited my comment to warn others about this mistake I've made. However after reverting my repository I still cannot find out why two of my routes were able to fetch from these endpoints from the handlers and then passing that information to the islands.

After reading more carefully both the source code and the docs I realize that "consume from API" is best suited (but not exclusive) to SPA's. Which Fresh does state it's not a supported architecture, I do owe you an apology for that :/

FuncProgLinux avatar Sep 29 '25 17:09 FuncProgLinux