Outdated docs for Docker and/or with DaisyUI.
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 checkoutbut 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
.mjsfiles not able to run - Versioning & readiness is misleading to users.
Things already tried
- Deleting
node_modulesanddeno.lock, then runningdeno install -r --allow-scripts - Changing
nodeModulesDirfromautotomanual - Using a new project base
- Running
deno task update - Cleaned docker images with
docker image prune -afand started from fresh - Excluded/Included
deno.lockin.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).
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? ._.
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
caddyas 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
nodeModulesDirset tomanualbecame a necessity since there is a bug in Deno, which prevents building the image with Podman on my local Ubuntu server when set toauto - This resulted in a few
npmpackages not finding their types automatically anymore, those needed to get added manually to theimportsection indeno.json - A
deno installstep is now mandatory as Deno no longer resolves/populates thenode_modulesfolder 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/
* 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:
-
mongooseormongo -
winston -
moment(I know, I know ๐)
This error looks very much like a missing
deno installstep: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:21DaisyUI 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
monoreposection 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 ๐ค
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.tsfile exists with aGETand aPOSThandler.
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'
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)
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 :/