jeasx 2.5.2 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esbuild.config.js CHANGED
@@ -12,24 +12,25 @@ const BROWSER_PUBLIC_ENV = Object.keys(ENV)
12
12
  env[`process.env.${key}`] = `"${ENV[key]}"`;
13
13
  return env;
14
14
  },
15
- { "process.env.BROWSER_PUBLIC_BUILD_TIME": BUILD_TIME },
15
+ Object({ "process.env.BROWSER_PUBLIC_BUILD_TIME": BUILD_TIME }),
16
16
  );
17
17
 
18
18
  /** @type esbuild.BuildOptions[] */
19
19
  const buildOptions = [
20
20
  {
21
21
  entryPoints: ["src/**/[*].*"],
22
- define: {
23
- "process.env.BUILD_TIME": BUILD_TIME,
24
- },
22
+ define: { "process.env.BUILD_TIME": BUILD_TIME },
25
23
  minify: process.env.NODE_ENV !== "development",
26
24
  logLevel: "info",
27
25
  color: true,
28
26
  bundle: true,
29
27
  sourcemap: process.sourceMapsEnabled,
30
28
  sourcesContent: false,
31
- outdir: "dist/server",
29
+ outdir: "dist",
30
+ publicPath: "/",
31
+ assetNames: "[dir]/[name]-[hash]",
32
32
  platform: "neutral",
33
+ format: "esm",
33
34
  packages: "external",
34
35
  ...ENV.ESBUILD_SERVER_OPTIONS?.(),
35
36
  },
@@ -42,24 +43,11 @@ const buildOptions = [
42
43
  bundle: true,
43
44
  sourcemap: process.sourceMapsEnabled,
44
45
  sourcesContent: true,
45
- outdir: "dist/browser",
46
+ outdir: "dist",
47
+ publicPath: "/",
48
+ assetNames: "[dir]/[name]-[hash]",
46
49
  platform: "browser",
47
50
  format: "esm",
48
- target: ["chrome130", "edge130", "firefox130", "safari18"],
49
- external: [
50
- "*.avif",
51
- "*.gif",
52
- "*.jpg",
53
- "*.jpeg",
54
- "*.png",
55
- "*.svg",
56
- "*.webp",
57
- "*.eot",
58
- "*.ttf",
59
- "*.otf",
60
- "*.woff",
61
- "*.woff2",
62
- ],
63
51
  ...ENV.ESBUILD_BROWSER_OPTIONS?.(),
64
52
  },
65
53
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jeasx",
3
- "version": "2.5.2",
3
+ "version": "2.6.0",
4
4
  "description": "Jeasx - the ease of JSX with the power of SSR",
5
5
  "keywords": [
6
6
  "async",
@@ -32,10 +32,10 @@
32
32
  "@fastify/cookie": "11.0.2",
33
33
  "@fastify/formbody": "8.0.2",
34
34
  "@fastify/multipart": "10.0.0",
35
- "@fastify/static": "9.1.1",
36
- "@types/node": "25.6.0",
35
+ "@fastify/static": "9.1.3",
36
+ "@types/node": "25.6.2",
37
37
  "esbuild": "0.28.0",
38
38
  "fastify": "5.8.5",
39
- "jsx-async-runtime": "2.1.1"
39
+ "jsx-async-runtime": "2.1.2"
40
40
  }
41
41
  }
package/serverless.js CHANGED
@@ -11,7 +11,7 @@ import env from "./env.js";
11
11
  const ENV = await env();
12
12
  const CWD = process.cwd();
13
13
  const NODE_ENV_IS_DEVELOPMENT = process.env.NODE_ENV === "development";
14
- const JEASX_ROUTE_CACHE_LIMIT = Math.floor(freemem() / 1024 / 1024);
14
+ const ROUTE_CACHE_LIMIT = Math.floor(freemem() / 1024 / 1024);
15
15
  const FASTIFY_SERVER = ENV.FASTIFY_SERVER ?? ((fastify2) => fastify2);
16
16
  var serverless_default = FASTIFY_SERVER(
17
17
  fastify({
@@ -25,8 +25,10 @@ var serverless_default = FASTIFY_SERVER(
25
25
  }).register(fastifyMultipart, {
26
26
  ...ENV.FASTIFY_MULTIPART_OPTIONS?.()
27
27
  }).register(fastifyStatic, {
28
- root: [["public"], ["dist", "browser"]].map((dir) => join(CWD, ...dir)),
28
+ root: ["public", "dist"].map((dir) => join(CWD, dir)),
29
29
  wildcard: false,
30
+ globIgnore: ["/**/\\[*\\].js?(.map)"],
31
+ // ignore server routes
30
32
  ...ENV.FASTIFY_STATIC_OPTIONS?.()
31
33
  }).decorateRequest("route", "").decorateRequest("path", "").addHook("onRequest", async (request) => {
32
34
  const index = request.url.indexOf("?");
@@ -57,7 +59,7 @@ async function handler(request, reply) {
57
59
  }
58
60
  if (module === void 0) {
59
61
  try {
60
- const modulePath = join(CWD, "dist", "server", `${route}.js`);
62
+ const modulePath = join(CWD, "dist", `${route}.js`);
61
63
  if (NODE_ENV_IS_DEVELOPMENT) {
62
64
  if (typeof require === "function") {
63
65
  if (require.cache[modulePath]) {
@@ -73,20 +75,19 @@ async function handler(request, reply) {
73
75
  modules.set(route, module);
74
76
  }
75
77
  } catch (e) {
76
- if (
77
- /* Node */
78
- e.code === "ENOENT" || /* Bun */
79
- e.code === "ERR_MODULE_NOT_FOUND"
80
- ) {
81
- if (!NODE_ENV_IS_DEVELOPMENT) {
82
- modules.set(route, null);
83
- }
84
- } else {
85
- throw e;
78
+ switch (e.code) {
79
+ case "ENOENT":
80
+ case "ENOTDIR":
81
+ case "ERR_MODULE_NOT_FOUND":
82
+ if (!NODE_ENV_IS_DEVELOPMENT) {
83
+ modules.set(route, null);
84
+ }
85
+ continue;
86
+ default:
87
+ throw e;
86
88
  }
87
- continue;
88
89
  } finally {
89
- if (modules.size > JEASX_ROUTE_CACHE_LIMIT) {
90
+ if (modules.size > ROUTE_CACHE_LIMIT) {
90
91
  modules.delete(modules.keys().next().value);
91
92
  }
92
93
  }
package/serverless.js.map CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["serverless.ts"],
4
- "mappings": "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",
4
+ "mappings": "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",
5
5
  "names": ["fastify"]
6
6
  }
package/serverless.ts CHANGED
@@ -18,7 +18,7 @@ const ENV = await env();
18
18
 
19
19
  const CWD = process.cwd();
20
20
  const NODE_ENV_IS_DEVELOPMENT = process.env.NODE_ENV === "development";
21
- const JEASX_ROUTE_CACHE_LIMIT = Math.floor(freemem() / 1024 / 1024);
21
+ const ROUTE_CACHE_LIMIT = Math.floor(freemem() / 1024 / 1024);
22
22
 
23
23
  declare module "fastify" {
24
24
  interface FastifyRequest {
@@ -51,8 +51,9 @@ export default FASTIFY_SERVER(
51
51
  ...(ENV.FASTIFY_MULTIPART_OPTIONS?.() as FastifyMultipartOptions),
52
52
  })
53
53
  .register(fastifyStatic, {
54
- root: [["public"], ["dist", "browser"]].map((dir) => join(CWD, ...dir)),
54
+ root: ["public", "dist"].map((dir) => join(CWD, dir)),
55
55
  wildcard: false,
56
+ globIgnore: ["/**/\\[*\\].js?(.map)"], // ignore server routes
56
57
  ...(ENV.FASTIFY_STATIC_OPTIONS?.() as FastifyStaticOptions),
57
58
  })
58
59
  .decorateRequest("route", "")
@@ -108,7 +109,7 @@ async function handler(request: FastifyRequest, reply: FastifyReply) {
108
109
  // Module was not loaded yet?
109
110
  if (module === undefined) {
110
111
  try {
111
- const modulePath = join(CWD, "dist", "server", `${route}.js`);
112
+ const modulePath = join(CWD, "dist", `${route}.js`);
112
113
  if (NODE_ENV_IS_DEVELOPMENT) {
113
114
  if (typeof require === "function") {
114
115
  // Bun: Remove module from cache before importing
@@ -128,19 +129,22 @@ async function handler(request: FastifyRequest, reply: FastifyReply) {
128
129
  modules.set(route, module);
129
130
  }
130
131
  } catch (e) {
131
- if (/* Node */ e.code === "ENOENT" || /* Bun */ e.code === "ERR_MODULE_NOT_FOUND") {
132
- if (!NODE_ENV_IS_DEVELOPMENT) {
133
- // Cache module as not found
134
- modules.set(route, null);
135
- }
136
- } else {
137
- // Module exists, but fails to load.
138
- throw e;
132
+ switch (e.code) {
133
+ case "ENOENT":
134
+ case "ENOTDIR":
135
+ case "ERR_MODULE_NOT_FOUND":
136
+ if (!NODE_ENV_IS_DEVELOPMENT) {
137
+ // Cache module as not found
138
+ modules.set(route, null);
139
+ }
140
+ continue;
141
+ default:
142
+ // Module exists, but fails to load.
143
+ throw e;
139
144
  }
140
- continue;
141
145
  } finally {
142
146
  // Remove oldest entry from cache if limit is reached
143
- if (modules.size > JEASX_ROUTE_CACHE_LIMIT) {
147
+ if (modules.size > ROUTE_CACHE_LIMIT) {
144
148
  modules.delete(modules.keys().next().value);
145
149
  }
146
150
  }
package/CHANGELOG.md DELETED
@@ -1,682 +0,0 @@
1
- # Changelog
2
-
3
- ## 2026-04-20 - Jeasx 2.5.2 released
4
-
5
- 🎉 This release resolves an issue where existing routes failed to load if a JavaScript error occurred during initialization (for example, when setting up a global scoped variable). Previously, this error was masked by returning a 404 route, causing the route to never be re-evaluated.
6
-
7
- ## 2026-04-16 - Jeasx 2.5.1 released
8
-
9
- 🎉 Upgrade to latest `@fastify/static` to fix [CVE-2026-6410](https://github.com/fastify/fastify-static/security/advisories/GHSA-pr96-94w5-mx2h) and [CVE-2026-6414](https://github.com/fastify/fastify-static/security/advisories/GHSA-x428-ghpx-8j92).
10
-
11
- Dependency updates: `@fastify/static@9.1.1`
12
-
13
- ## 2026-04-15 - Jeasx 2.5.0 released
14
-
15
- 🎉 This release removes all non-essential Fastify configuration options from the Jeasx core, aligning it more closely with Fastify’s well-chosen default settings.
16
-
17
- To maintain your previous behavior, I recommend making minor adjustments to your configuration via `.env.js`:
18
-
19
- ```js
20
- export default {
21
- // ...
22
-
23
- FASTIFY_SERVER_OPTIONS: () => ({
24
- logger: { level: process.env.NODE_ENV === "development" ? "error" : "info" },
25
- // 'disableRequestLogging' should be removed.
26
- }),
27
-
28
- FASTIFY_MULTIPART_OPTIONS: () => ({
29
- // Only relevant if you use file uploads in your project.
30
- attachFieldsToBody: "keyValues",
31
- }),
32
-
33
- // ...
34
- };
35
- ```
36
-
37
- Additionally, the configured Fastify logger is now used for error logging, replacing the previous use of `console.error`.
38
-
39
- This release also addresses [CVE-2026-33806](https://github.com/fastify/fastify/security/advisories/GHSA-247c-9743-5963) by upgrading to the latest Fastify version.
40
-
41
- Dependency updates: `fastify@5.8.5`, `@types/node@25.6.0`
42
-
43
- ## 2026-04-09 - Jeasx 2.4.8 released
44
-
45
- 🎉 Just some dependency updates...
46
-
47
- Dependency updates: `@fastify/multipart@10.0.0`, `@fastify/static@9.1.0`
48
-
49
- ## 2026-04-04 - Jeasx 2.4.7 released
50
-
51
- 🎉 Just some dependency updates...
52
-
53
- Dependency updates: `jsx-async-runtime@2.1.1`, `esbuild@0.28.0`, `@types/node@25.5.2`
54
-
55
- ## 2026-04-02 - Jeasx 2.4.6 released
56
-
57
- 🎉 This release updates the `tsconfig.json` settings to fully support the latest TypeScript 6 changes. Now, the latest version of VSCode runs smoothly without any warnings.
58
-
59
- Dependency updates: `esbuild@0.27.7`
60
-
61
- ## 2026-03-25 - Jeasx 2.4.5 released
62
-
63
- 🎉 Just a patch update to stay synced with latest `jsx-async-runtime`.
64
-
65
- Dependency updates: `jsx-async-runtime@2.1.0`
66
-
67
- ## 2026-03-23 - Jeasx 2.4.4 released
68
-
69
- 🎉 Just a patch release to update Fastify to fix [CVE-2026-3635](https://github.com/fastify/fastify/security/advisories/GHSA-444r-cwp2-x5xf).
70
-
71
- Dependency updates: `fastify@5.8.4`
72
-
73
- ## 2026-03-14 - Jeasx 2.4.3 released
74
-
75
- 🎉 Just some dependency updates...
76
-
77
- Dependency updates: `fastify@5.8.2`, `esbuild@0.27.4`, `@types/node@25.5.0`
78
-
79
- ## 2026-03-05 - Jeasx 2.4.2 released
80
-
81
- 🎉 Just a patch release to update Fastify to fix [CVE-2026-3419](https://github.com/fastify/fastify/security/advisories/GHSA-573f-x89g-hqp9).
82
-
83
- Jeasx uses from now on [trusted publishing for npm packages](https://docs.npmjs.com/trusted-publishers) to release new versions.
84
-
85
- Dependency updates: `fastify@5.8.1`, `jsx-async-runtime@2.0.3`
86
-
87
- ## 2026-03-02 - Jeasx 2.4.1 released
88
-
89
- 🎉 This release introduces route prop inheritance from guards. Guards can return objects whose entries are used as additional props for your routes. Previously, only props from the closest guard were used. With this update, props from all guards along the route are collected and passed down. If multiple guards provide props with the same key, the value from the guard nearest to the route takes precedence and overwrites earlier ones.
90
-
91
- Dependency updates: `@types/node@25.3.3`
92
-
93
- ## 2026-02-20 - Jeasx 2.4.0 released
94
-
95
- 🎉 This release is both a step forward and a step back: the recently introduced support for MDX has been removed from the core project. Jeasx aims to keep its core as lean as possible, so this change aligns with the project's overall goals. Since MDX is not essential for every Jeasx website or application, it makes sense to move it out of the core.
96
-
97
- Another key goal of Jeasx is to empower users to implement their own custom solutions in userland, providing the right tools to do so. In short, while MDX remains a fantastic technology for content-driven websites, Jeasx now lets you configure MDX support yourself through a much improved configuration system for its base technologies like esbuild and Fastify.
98
-
99
- For esbuild, two new configuration options are available: `ESBUILD_SERVER_OPTIONS` and `ESBUILD_BROWSER_OPTIONS`. These can be defined as functions in `.env.js` that return additional configuration settings for esbuild.
100
-
101
- Why use functions instead of plain objects for the configuration? Because using functions allows configurations to be created lazily - only when needed - which is especially helpful for more complex setups over time.
102
-
103
- If you want to use MDX with Jeasx, simply run `npm install @mdx-js/esbuild` and add the configuration below to `ESBUILD_SERVER_OPTIONS` in `.env.js`.
104
-
105
- If you've used `ESBUILD_BROWSER_TARGET` in the past, you have to move this configuration to `ESBUILD_BROWSER_OPTIONS` as shown below.
106
-
107
- ```jsx
108
- import mdx from "@mdx-js/esbuild";
109
-
110
- export default {
111
- /** @type {() => import("esbuild").BuildOptions} */
112
- ESBUILD_SERVER_OPTIONS: () => ({
113
- plugins: [
114
- mdx({
115
- development: process.env.NODE_ENV === "development",
116
- jsxImportSource: "jsx-async-runtime",
117
- elementAttributeNameCase: "html",
118
- stylePropertyNameCase: "css",
119
- }),
120
- ],
121
- }),
122
-
123
- /** @type {() => import("esbuild").BuildOptions} */
124
- ESBUILD_BROWSER_OPTIONS: () => ({
125
- target: ["chrome130", "edge130", "firefox130", "safari18"],
126
- }),
127
- };
128
- ```
129
-
130
- The existing configuration options for Fastify (such as `FASTIFY_SERVER_OPTIONS`, `FASTIFY_COOKIE_OPTIONS`, `FASTIFY_MULTIPART_OPTIONS`, `FASTIFY_STATIC_OPTIONS`) now require a minor change: they must be defined as functions instead of plain objects.
131
-
132
- Additionally, you can now customize the fastify server instance using the optional `FASTIFY_SERVER` function. This function receives the created server instance and should return the modified version. This feature is especially useful when integrating existing Fastify plugins like `@fastify/compress`, as demonstrated below.
133
-
134
- ```jsx
135
- import fastifyCompress from "@fastify/compress";
136
-
137
- const NODE_ENV_IS_DEVELOPMENT = process.env.NODE_ENV === "development";
138
-
139
- export default {
140
- /** @type {(fastify: import("fastify").FastifyInstance) => import("fastify").FastifyInstance} */
141
- FASTIFY_SERVER: (fastify) => fastify.register(fastifyCompress),
142
-
143
- /** @type {() => import("fastify").FastifyServerOptions} */
144
- FASTIFY_SERVER_OPTIONS: () => ({
145
- disableRequestLogging: NODE_ENV_IS_DEVELOPMENT,
146
- bodyLimit: 1024 * 1024,
147
- }),
148
-
149
- /** @type {() => import("@fastify/static").FastifyStaticOptions} */
150
- FASTIFY_STATIC_OPTIONS: () => ({
151
- immutable: !NODE_ENV_IS_DEVELOPMENT,
152
- maxAge: NODE_ENV_IS_DEVELOPMENT ? 0 : "365d",
153
- }),
154
- };
155
- ```
156
-
157
- Another notable change is that the fallback content-type (`text/html`) for routes is now set as late as possible. This means you can return plain JavaScript objects from routes, which will be automatically sent as `application/json` by default - without needing to explicitly specify the content-type in your code. This update brings Jeasx in line with Fastify’s default behavior.
158
-
159
- Additionally, you can now define routes directly from simple `*.json` or `*.txt` files - perfect for creating static endpoints like a health check or a `robots.txt` file right in your routes folder.
160
-
161
- Dependency updates: `@types/node@25.3.0`
162
-
163
- ## 2026-02-12 - Jeasx 2.3.2 released
164
-
165
- 🎉 Upgraded to @types/node@25, enabling seamless development with Node 25 while maintaining compatibility for Node 24 users.
166
-
167
- Dependency updates: `esbuild@0.27.3`, `@types/node@25.2.3`
168
-
169
- ## 2026-02-04 - Jeasx 2.3.1 released
170
-
171
- 🎉 Just a patch release to update Fastify to fix [CVE-2026-25224](https://github.com/fastify/fastify/security/advisories/GHSA-mrq3-vjjr-p77c).
172
-
173
- Additionally, I performed minor refactorings identified by [oxlint](https://oxc.rs/docs/guide/usage/linter.html) and replaced `prettier` with [oxfmt](https://oxc.rs/docs/guide/usage/formatter), a high-performance formatter optimized for the JavaScript ecosystem.
174
-
175
- Dependency updates: `fastify@5.7.4`, `@types/node@24.10.10`
176
-
177
- ## 2026-01-30 - Jeasx 2.3.0 released
178
-
179
- 🎉 This release introduces support for [MDX](https://mdxjs.com), enabling you to seamlessly embed JSX within Markdown content. Just create a route with a `.mdx` extension, and you’re all set to enhance your websites and blogs with Markdown enriched by dynamic JSX components.
180
-
181
- ```jsx
182
- import Layout from "./Layout";
183
-
184
- <Layout title="MDX - Markdown for the component era">
185
- # MDX as content companion alongside JSX You can easily access existing `props` in MDX: - Current
186
- url: {props.request.url}
187
- </Layout>;
188
- ```
189
-
190
- You can also create MDX-based components for use within JSX by importing them with their full `.mdx` file extension into your JSX routes or components.
191
-
192
- Since MDX supports a variety of plugins - and Jeasx provides only the MDX core to stay focused on infrastructure while letting users handle customization - the overall configuration for Jeasx has been significantly improved. Now, the configuration object from an `.env.js` file is imported directly into both the build process and server runtime, allowing you to use package imports seamlessly. Previously, (de)serializing the configuration via `process.env` restricted this capability and limited advanced setups.
193
-
194
- **Please note:** Variables loaded from `.env.js` now consistently overwrite any existing environment variables. This ensures predictable and consistent behavior across your configuration.
195
-
196
- Here’s an example of how to configure the MDX engine: if you want to enable GitHub-flavored Markdown (`remark-gfm`), add syntax highlighting (`rehype-prism-plus`), and generate IDs for your headings (`rehype-slug`), you can install and configure these plugins accordingly in `.env.js`.
197
-
198
- ```js
199
- import rehypePrismPlus from "rehype-prism-plus";
200
- import rehypeSlug from "rehype-slug";
201
- import remarkGFM from "remark-gfm";
202
-
203
- export default {
204
- /** @type import("@mdx-js/esbuild").Options */
205
- ESBUILD_MDX_OPTIONS: {
206
- remarkPlugins: [[remarkGFM, { singleTilde: false }]],
207
- rehypePlugins: [rehypePrismPlus, [rehypeSlug, { prefix: "jeasx-" }]],
208
- },
209
- //...
210
- };
211
- ```
212
-
213
- For a full overview of available configuration options and plugins, check out the excellent documentation of [@mdx-js/esbuild](https://mdxjs.com/packages/esbuild).
214
-
215
- **Please note:** The update to the Jeasx configuration introduced a minor change in how `ESBUILD_BROWSER_TARGET` is specified to ensure consistency across the configuration. Previously, a comma-separated string was accepted and parsed as customization. Going forward, you must provide a proper JSON array (or its stringified form when using traditional `.env` files or the process environment).
216
-
217
- ```js
218
- export default {
219
- /** @type import("esbuild").BuildOptions["target"] */
220
- ESBUILD_BROWSER_TARGET: ["chrome130", "edge130", "firefox130", "safari18"],
221
- //...
222
- };
223
- ```
224
-
225
- Dependency updates: `fastify@5.7.2`, `@fastify/multipart@9.4.0`
226
-
227
- ## 2026-01-17 - Jeasx 2.2.2 released
228
-
229
- 🎉 This release now preserves the original status code when a 404 page is accessed directly (defaults to 200). This improvement makes it easier to use Jeasx as a static site generator and to fetch the 404 page with common tools for saving it to a file system.
230
-
231
- While Jeasx is fundamentally a server-side rendering framework, there are valid use cases where serving a static page alone is sufficient. For example, you can use `wget` to download a Jeasx website to a www-directory with just a single line:
232
-
233
- ```bash
234
- wget --mirror --page-requisites --no-host-directories --directory-prefix=www http://localhost:3000 http://localhost:3000/404
235
- ```
236
-
237
- Have a look at the [Dockerfile](https://github.com/jeasx/jeasx-website/blob/main/Dockerfile) of the Jeasx website to see how things can be wired up for serving a static export with Caddy as web server.
238
-
239
- If you want to restore the old behaviour (directly calling /404 resulting in status code 404), you can simple add `reply.status(404)` to your `/[404]` handler.
240
-
241
- Dependency updates: `fastify@5.7.1`, `@fastify/static@9.0.0`, `@types/node@24.10.9`
242
-
243
- ## 2025-12-21 - Jeasx 2.2.1 released
244
-
245
- 🎉 Just a patch release with a minor cleanup for explicit path joins in `serverless.ts`.
246
-
247
- Dependency updates: `esbuild@0.27.2`, `jsx-async-runtime@2.0.2`, `@types/node@24.10.4`
248
-
249
- ## 2025-12-01 - Jeasx 2.2.0 released
250
-
251
- 🎉 This release introduces a more flexible configuration approach for the underlying Fastify server. You can now customize all Fastify options (including those for all used plugins) according to your needs, without having to use the formerly fixed and very restrictive set of environment variables. This change was made to eliminate the need for increasingly specific environment variables to customise the default behaviour of Jeasx.
252
-
253
- **Breaking change**: The previously supported environment variables (`FASTIFY_​BODY_​LIMIT, FASTIFY_​DISABLE_​REQUEST_​LOGGING, FASTIFY_​REWRITE_​URL, FASTIFY_​STATIC_​HEADERS, FASTIFY_​TRUST_​PROXY, FASTIFY_​MULTIPART_​ATTACH_​FIELDS_​TO_​BODY`) have been completely removed. While this may seem inconvenient for a minor release, the process of migrating your setup to the new configuration approach usually takes less than a minute. This streamlines the code base and documentation, as these features are presumably seldom used.
254
-
255
- To configure Fastify (or a specific plugin), you can now use simple JSON objects which mirror the corresponding Fastify options. Have a look at the linked Fastify documentation for a reference of all existing options:
256
-
257
- - [`FASTIFY_SERVER_OPTIONS`](https://fastify.dev/docs/latest/Reference/Server/)
258
- - [`FASTIFY_COOKIE_OPTIONS`](https://github.com/fastify/fastify-cookie#options)
259
- - [`FASTIFY_FORMBODY_OPTIONS`](https://github.com/fastify/fastify-formbody#options)
260
- - [`FASTIFY_MULTIPART_OPTIONS`](https://github.com/fastify/fastify-multipart#options)
261
- - [`FASTIFY_STATIC_OPTIONS`](https://github.com/fastify/fastify-static#options)
262
-
263
- To optimise the developer experience, it is highly recommended that you use the recently introduced `.env.js` file to provide these configuration options. Alternatively, you can also provide them via `.env` or your process environment. Jeasx comes with a minimal set of reasonable [Fastify defaults](https://github.com/jeasx/jeasx/blob/main/serverless.ts), but you can also overwrite them if necessary.
264
-
265
- Some Fastify options, such as `rewriteUrl` or `setHeaders`, take a function as a parameter. Jeasx supports this use case by deserialising the stringified function code when the server starts up.
266
-
267
- ### Example configuration
268
-
269
- ```js
270
- const NODE_ENV_IS_DEVELOPMENT = process.env.NODE_ENV === "development";
271
-
272
- export default {
273
- /** @type import("fastify").FastifyServerOptions */
274
- FASTIFY_SERVER_OPTIONS: {
275
- disableRequestLogging: NODE_ENV_IS_DEVELOPMENT,
276
- bodyLimit: 2 * 1024 * 1024,
277
- rewriteUrl: (req) => String(req.url).replace(/^\/jeasx/, ""),
278
- },
279
-
280
- /** @type import("@fastify/static").FastifyStaticOptions */
281
- FASTIFY_STATIC_OPTIONS: {
282
- maxAge: NODE_ENV_IS_DEVELOPMENT ? 0 : "365d",
283
- },
284
-
285
- /** @type import("@fastify/cookie").FastifyCookieOptions */
286
- // FASTIFY_COOKIE_OPTIONS: {},
287
-
288
- /** @type import("@fastify/formbody").FastifyFormbodyOptions */
289
- // FASTIFY_FORMBODY_OPTIONS: {},
290
-
291
- /** @type import("@fastify/multipart").FastifyMultipartOptions */
292
- // FASTIFY_MULTIPART_OPTIONS: {},
293
- };
294
- ```
295
-
296
- Another improvement has been made by introducing an automatic approach to determine the maximum size of the internal route cache. Depending on the amount of free memory available at startup, the maximum number of cache entries is calculated. This approach strikes a balance, ensuring the cache is large enough for large-scale projects while keeping maximum memory consumption within reasonable limits given the available resources. This means that you no longer need to worry about providing ~~`JEASX_ROUTE_CACHE_LIMIT`~~ via the environment.
297
-
298
- Dependency updates: `@types/node@24.10.1`
299
-
300
- ## 2025-11-10 - Jeasx 2.1.1 released
301
-
302
- 🎉 Enhanced configuration for @fastify/static, so you can serve pre-compressed static files (see [fastify docs](https://github.com/fastify/fastify-static?tab=readme-ov-file#precompressed)) from `public` and `dist/browser`. Just run `gzip -rk public dist/browser` as post build for gzipping your static assets. This might be useful if you don't want to run a reverse proxy in front of your Jeasx application and serve compressed files nevertheless. Setting up compression for dynamic content can be wired up in userland via a root guard:
303
-
304
- ```js
305
- import { promisify } from "node:util";
306
- import { gzip } from "node:zlib";
307
-
308
- export default function ({ request, reply }) {
309
- this.responseHandler = (payload) => {
310
- if (typeof payload === "string" && request.headers["accept-encoding"]?.includes("gzip")) {
311
- reply.header("content-encoding", "gzip");
312
- return promisify(gzip)(payload);
313
- } else {
314
- return payload;
315
- }
316
- };
317
- }
318
- ```
319
-
320
- Updated `moduleResolution` to `bundler` in `tsconfig.json`.
321
-
322
- Dependency updates: `jsx-async-runtime@2.0.1`, `fastify@5.6.2`, `esbuild@0.27.0`, `@types/node@24.9.2`
323
-
324
- ## 2025-10-28 - Jeasx 2.1.0 released
325
-
326
- 🎉 Environment vars can now be loaded from a JavaScript file (`.env.js`) additionally to existing .env-files. This allows enhanced environment setups depending on your workflows.
327
-
328
- Node 24 (LTS) is the official default runtime from now on.
329
-
330
- Dependency updates: `@fastify/multipart@9.3.0`, `@fastify/static@8.3.0`, `@types/node@24.9.1`
331
-
332
- ## 2025-10-15 - Jeasx 2.0.1 released
333
-
334
- 🎉 This releases fixes status codes for fallback 404 routes. Due to an unnoticed bug introduced by a minor refactoring, 404-routes were delivered with `status=200`, now it is the correct `status=404` again. This might impact your SEO score, so an update is highly recommended.
335
-
336
- Dependency updates: `esbuild@0.25.11`
337
-
338
- ## 2025-10-12 - Jeasx 2.0.0 released
339
-
340
- 🎉 Approximately one year after the release of Jeasx 1.0 I'm proud to announce the release of Jeasx 2.0.
341
-
342
- It's a funny story... every time I think Jeasx is feature-complete, there is still some more room to improve. Although the main idea behind Jeasx development still holds true: focus on a lean and stable core and let developers do all their magic in userland.
343
-
344
- This release is focused on security and comes with a major breaking change: all HTML markup is escaped by default from now on, so you don't have to escape dangerous user input on your own anymore. This way the developer experience is improved and the actual performance costs for automatic escaping are neglible due to the reuse of the highly optimized fast-escape-html library.
345
-
346
- If you need to include literal HTML in your JSX templates (e.g. HTML snippets from a CMS), you can use a special object syntax to opt out of escaping: `{{ html: "<p>Some HTML from a CMS</p>" }}`
347
-
348
- If you want to migrate from Jeasx 1.0 to Jeasx 2.0 with automatic HTML escaping enabled, you'll need to remove all calls to #escapeEntities() and modify the HTML declaration in your layouts (`{{ html: <!DOCTYPE html>" }}`). Then you should check where you need to render literal HTML (or other code) and apply the required changes to opt out of escaping (e.g. `<div>{ wysiwygContent }</div>; to <div>{{ html: wysiwygContent }}</div>`).
349
-
350
- If you want to restore the non-escaping behaviour of Jeasx &lt; v2, you can set `jsxEscapeHTML = false` in the root guard. This way HTML escaping is disabled globally.
351
-
352
- Another internal change is the renaming of the directories in the output directory (`dist`): `routes` is now called `server` alongside the `browser` directory.
353
-
354
- Dependency updates: `jsx-async-runtime@2.0.0, @types/node@22.18.10`
355
-
356
- ## 2025-09-29 - Jeasx 1.9.0 released
357
-
358
- 🎉 This release drops the constraint that you had to put all routes into a dedicated routes-directory and all JavaScript & CSS into a dedicated browser-directory. From now on you can use any directory layout in your projects as you like. You can still use the proven `browser/routes` layout, but you don't have to.
359
-
360
- This feature enables the co-location of server and browser code in the same directory which might be a better default for your workflows.
361
-
362
- The only remaining constraint is to mark server routes with brackets (e.g. `[news].jsx`) and browser-bundled assets as index-files (e.g. `index.js` or `index.css`).
363
-
364
- Please note: This feature is enabled by dropping the hard coded outbase-directories in the esbuild configuration. If the outbase directory isn't specified, it defaults to the lowest common ancestor directory among all input entry point paths.
365
-
366
- If you run into an edge case (e.g. your browser bundles won't load anymore), here's how to fix it: if you store all your assets in browser/assets and request your assets via `/assets/...`, this won't work anymore, because assets is now the lowest common ancestor directory and is removed by esbuild. Simple fix: just put an empty `index.js` into browser directory, so this directory is lowest common ancestor directory again.
367
-
368
- Bumbed the default `ESBUILD_BROWSER_TARGET` to `"chrome130", "edge130", "firefox130", "safari18"`.
369
-
370
- Dependency updates: `fastify@5.6.1, esbuild@0.25.10, @types/node@22.18.6`
371
-
372
- ## 2025-09-11 - Jeasx 1.8.6 released
373
-
374
- 🎉 This release bumps dependencies to the latest and greatest versions.
375
-
376
- Dependency updates: `fastify@5.6.0, fastify/multipart@9.2.1, @types/node@22.18.1`
377
-
378
- ## 2025-08-13 - Jeasx 1.8.5 released
379
-
380
- 🎉 This release bumps dependencies to the latest and greatest versions.
381
-
382
- Dependency updates: `fastify@5.5.0, jsx-async-runtime@1.0.4, esbuild@0.25.9, @types/node@22.17.1`
383
-
384
- ## 2025-08-03 - Jeasx 1.8.4 released
385
-
386
- 🎉 This release bumps dependencies to the latest and greatest versions.
387
-
388
- Dependency updates: `esbuild@0.25.8, @types/node@22.17.0`
389
-
390
- ## 2025-07-11 - Jeasx 1.8.3 released
391
-
392
- 🎉 This release bumps dependencies to the latest and greatest versions.
393
-
394
- Dependency updates: `jsx-async-runtime@1.0.3, esbuild@0.25.6, @types/node@22.16.3`
395
-
396
- ## 2025-06-13 - Jeasx 1.8.2 released
397
-
398
- 🎉 This release changes the default options for @fastify/multipart. From now on the default for `attachFieldsToBody` is `keyValues` which provides all data for form body requests (e.g. uploads) directly via request.body. Have a look at the Fastify documentation for code examples and options.
399
-
400
- This change makes the required code for handling form body requests much easier:
401
-
402
- ```js
403
- // Change this code...
404
- const file = await request.file();
405
- const upload = await file.toBuffer();
406
- const format = file.fields["format"]["value"];
407
-
408
- // ... to this code.
409
- const upload = request.body["upload"];
410
- const format = request.body["format"];
411
- ```
412
-
413
- Please note: This change might break your code. If you want to revert to the old behaviour, you can set the following environment variable: `FASTIFY_​MULTIPART_​ATTACH_​FIELDS_​TO_​BODY=false`
414
-
415
- Dependency updates: `fastify@5.4.0, @types/node@22.15.31`
416
-
417
- ## 2025-05-28 - Jeasx 1.8.1 released
418
-
419
- 🎉 Just some dependency updates...
420
-
421
- Dependency updates: `jsx-async-runtime@1.0.2, fastify@5.3.3, fastify/static@8.2.0, esbuild@0.25.5, @types/node@22.15.23`
422
-
423
- ## 2025-05-12 - Jeasx 1.8.0 released
424
-
425
- 🎉 This release introduces a custom error handler to provide user-friendly error messages for internal server errors and to facilitate team notifications.
426
-
427
- To set up an error handler, simply register it in a route of your choice:
428
-
429
- ```js
430
- this.errorHandler = async (error) => {
431
- console.error("❌", error);
432
- return <h1>Internal error</h1>;
433
- };
434
- ```
435
-
436
- An error handler is called with this as context, allowing easy access to your context setup.
437
-
438
- **Breaking change:** If you use a response handler, you'll need to change the name from this.response to this.responseHandler. This aligns the response handler with the introduced error handler. We apologize for any inconvenience, but since this is a seldom-used feature, we aim to streamline the codebase by aligning it without maintaining deprecated code.
439
-
440
- As additional feature, a response handler is now called with this as the context, so you can access your existing context.
441
-
442
- Dependency updates: `esbuild@0.25.4, @types/node@22.15.17`
443
-
444
- ## 2025-05-03 - Jeasx 1.7.3 released
445
-
446
- 🎉 This release introduces a performance improvement by switching the internal route-to-module cache implementation from a JavaScript object to a Map. This change allows for better management of cache entries, enabling the configuration of a maximum cache limit. To take advantage of this, a new configuration option `JEASX_ROUTE_CACHE_LIMIT` has been added.
447
-
448
- Dependency updates: `jsx-async-runtime@1.0.1, esbuild@0.25.3, @types/node@22.15.3`
449
-
450
- ## 2025-04-21 - Jeasx 1.7.2 released
451
-
452
- 🎉 This release is brings only minor changes:
453
-
454
- `FASTIFY_STATIC_HEADERS`: Apply all matching headers to the current path. Use an empty string ("") as first rule to set default headers, which can be overridden by more specific rules later. Please checkout the updated configuration.
455
-
456
- Please note: You may need to adjust your existing configuration by moving the wildcard rule to the top of the JSON file to ensure it can be overridden by more specific rules defined below.
457
- env.sh: Removed logging of loaded environment files. Minor refactoring to clean up the code.
458
-
459
- Dependency updates: `fastify@5.3.2, @types/node@22.14.1`
460
-
461
- ## 2025-03-31 - Jeasx 1.7.1 released
462
-
463
- 🎉 This release enhances support for Bun as an alternative JavaScript runtime for both development and production. Use `bun -b dev` to start development with Jeasx and Bun. With Bun 1.2.8, the entire Jeasx expo functions without any issues. While Node.js remains the primary focus of the project, Bun support will continue to improve. Having multiple options is always beneficial.
464
-
465
- Route loading in development has been enhanced. It now relies on the modification time of the module, eliminating the need to calculate a hash for the file content. Additionally, a redundant file existence check for route handlers has been removed, resulting in more streamlined core code.
466
-
467
- From now on, source maps for `serverless.js` are provided to enhance debugging.
468
-
469
- Dependency updates: `esbuild@0.25.2`
470
-
471
- ## 2025-03-27 - Jeasx 1.7.0 released
472
-
473
- 🎉 This release removes `pm2` as a dependency and utilizes the powerful file watching capabilities of esbuild directly. This enhancement significantly improves build performance because esbuild only re-compiles linked files. Additionally, sharing code between the server and browser now works seamlessly without any additional configurations.
474
-
475
- As an added benefit, Jeasx now works with Bun as an alternative JavaScript runtime, although this setup is not yet recommended for development or production.
476
-
477
- Dependency updates: `@types/node@22.13.14`
478
-
479
- ## 2025-03-26 - Jeasx 1.6.3 released
480
-
481
- 🎉 This release fixes a bug with the recently introduced env file loading. The env files were loaded in the wrong order, so that overwriting existing env variables didn't work.
482
-
483
- Dependency updates: `fastify@5.2.2, @types/node@22.13.13`
484
-
485
- ## 2025-03-19 - Jeasx 1.6.2 released
486
-
487
- 🎉 This release introduces a `try/catch` block in the central request handler, ensuring that proper error messages are logged. Additionally, it enables sourcemaps for both server and browser code, making debugging a breeze.
488
-
489
- To enable sourcemap support for Node.js, add the following code to the root of your project as a .npmrc file:
490
-
491
- `node-options=--enable-source-maps`
492
-
493
- If you are using Docker, you need to modify the following lines in your Dockerfile to enable support for `.npmrc`:
494
-
495
- ```bash
496
- # RUN npx jeasx build
497
- RUN npm run build
498
- # CMD ["npx","jeasx","start"]
499
- CMD ["npm","start"]
500
- ```
501
-
502
- ## 2025-03-15 - Jeasx 1.6.1 released
503
-
504
- 🎉 This releases replaces the dependency on `dotenv-flow` with a native implementation provided by Node.js (using `process.loadEnvFile` introduced with Node v20.12.0) to load environment variables from .env-files. The order of loading .env-files is the same as before:
505
-
506
- ```text
507
- .env.defaults
508
- .env
509
- .env.local
510
- .env.[NODE_ENV] (e.g. .env.development or .env.production)
511
- .env.[NODE_ENV].local (e.g. .env.development.local or .env.production.local)
512
- ```
513
-
514
- **Breaking change:** If you use .env-files to configure Jeasx and deploy to Vercel, please update your `vercel.json`. You'll need to change `"includeFiles": "{node_modules,dist,public}/**/*"` to `"includeFiles": "./**/*"to` make sure Vercel includes the .env-files in the deployment.
515
-
516
- Additionally a fix for correctly parsing environment variables to configure Fastify (`FASTIFY_DISABLE_REQUEST_LOGGING, FASTIFY_TRUST_PROXY`) was implemented.
517
-
518
- Dependency updates: `jsx-async-runtime@1.0.0, esbuild@0.25.1, pm2@6.0.5`
519
-
520
- Please note: version 1.6.0 was unpublished from NPM right after the release due to a mistake.
521
-
522
- ## 2025-03-09 - Jeasx 1.5.0 released
523
-
524
- 🎉 This release features two new configurations:
525
-
526
- `FASTIFY_REWRITE_URL` allows you to rewrite incoming URLs. Useful when running behind proxies or when you want to fake URLs.
527
- `JEASX_BUILD_ROUTES_IGNORE_WATCH` allows watching for changes in src/browser when importing browser code into server code.
528
-
529
- Dependency updates: `@types/node@22.13.10`
530
-
531
- ## 2025-03-01 - Jeasx 1.4.1 released
532
-
533
- 🎉 This release features an updated `jsx-async-runtime@0.8.1` which brings typings for SVGs for a better developer experience in the IDE of your choice.
534
-
535
- 3rd-party dependencies were updated to the latest versions: `@fastify/static@8.1.1, @types/node@22.13.5`
536
-
537
- ## 2025-02-12 - Jeasx 1.4.0 released
538
-
539
- 🎉 This release adds the route property to the current endpoint handler (e.g., `/[index]` or `/bar/[...path]`) to the request object (accessible via request.route). This makes it much easier to calculate trailing path segments for wildcard routes.
540
-
541
- Also several dependencies were updated to the latest versions: `esbuild@0.25.0, @fastify/static@8.1.0, @fastify/multipart@9.0.3, @fastify/formbody@8.0.3, @types/node@22.13.1`
542
-
543
- ## 2025-01-18 - Jeasx 1.3.0 released
544
-
545
- 🎉 We are excited to announce the release of `jsx-async-runtime@0.7.1`, which now includes proper typings for all HTML attributes in accordance with the Mozilla Developer Network. This ensures that code completion in your IDE for all HTML attributes works now as expected in Jeasx. Special thanks to Rebecca for highlighting this issue!
546
-
547
- The updated version of `jsx-async-runtime` now supports using an array of strings for the class attribute, making it easier to create complex classnames. You can now construct classnames using plain strings or template strings, an array of strings, or an object, covering most use-cases known from other libraries like classnames.
548
-
549
- As always, we've updated to the latest versions of our dependencies: `fastify/formbody@8.0.2, fastify/multipart@9.0.2, fastify/static@8.0.4, types/node@22.10.7`
550
-
551
- ## 2025-01-06 - Jeasx 1.2.2 released
552
-
553
- 🎉 This release is just a minor dependency update: `fastify@5.2.1, fastify/cookie@11.0.2, types/node@22.10.5`
554
-
555
- ## 2024-12-12 - Jeasx 1.2.1 released
556
-
557
- 🎉 This release fixes a bug introduced by the recently introduced route caching feature: if a guard returned different response types (e.g. JSX code for a forbidden route, otherwise props for the guarded routes), the guarded routes weren't resolved anymore.
558
-
559
- ## 2024-12-07 - Jeasx 1.2.0 released
560
-
561
- 🎉 This release brings a major performance boost (about 2-5 times faster in benchmarks) by introducing runtime caches for resolved routes and loaded JavaScript modules. The caches are only used in production and won't interfere with your development workflow. This change was triggered by a PR submitted by Bryce, Kudos to him for bringing this topic onto the radar.
562
-
563
- It also features an update to `jsx-async-runtime` which provides more accurate and also deprecated typings for HTML tags and attributes according to the fantastic HTML reference from the Mozilla Development Network.
564
-
565
- Added two new environment variables (`FASTIFY_DISABLE_REQUEST_LOGGING` and `FASTIFY_TRUST_PROXY`) to give you more control over how Jeasx should behave in different environments.
566
-
567
- ## 2024-12-01 - Jeasx 1.1.0 released
568
-
569
- 🎉 Migrated from dotenv to dotenv-flow, so you can use NODE_ENV-specific .env\* files (like `.env.development`) to configure different environments for production and development. This is useful to disable caching headers (e.g. via `FASTIFY_STATIC_HEADERS`) in development, as Jeasx applies `FASTIFY_STATIC_HEADERS` in development from now on for a more consistent developer experience. See updated .env-files in the quickstart-project for an example how to disable caching in development. This is only needed if you have configured `FASTIFY_STATIC_HEADERS` for your existing projects.
570
-
571
- Bumped default environment variable `ESBUILD_BROWSER_TARGET` to more recent browser versions (e.g. `chrome126, edge126, firefox128, safari17`). If you want to stick with older versions, you can override it via the environment. Learn more about possible values at the esbuild website.
572
-
573
- Updated `jsx-async-runtime` which fixes a bug in escapeEntities which escaped existing &amp; two times. This release also removes the deprecated `renderToString` function. Simply replace it with `jsxToString`.
574
-
575
- The default host is now :: which binds to all available network interfaces (e.g. `IPv6`). You can change it via the `HOST` environment variable (e.g. `HOST=0.0.0.0` for the old behaviour). The change is especially useful to connect to Jeasx via private networking on hosting platforms like Railway.
576
-
577
- ## 2024-11-15 - Jeasx 1.0.2 released
578
-
579
- 🎉 Disabled cache-control for fastify-static, so proper Cache-Control response header could be applied via the environment variable `FASTIFY_STATIC_HEADERS`. Have a look at the env-file in the quickstart project for an example.
580
-
581
- ## 2024-11-01 - Jeasx 1.0.1 released
582
-
583
- 🎉 This version brings official support for Node 22. Also dependencies were updated to latest versions of `fastify@5.0.1, fastify/static@8.0.2, fastify/cookie@11.0.1`. Added new examples for template fragments in combination with HTMX and image optimization with sharp.
584
-
585
- ## 2024-10-04 - Jeasx 1.0.0 released
586
-
587
- It's finally here! Jeasx 1.0.0 is ready for production. We are proud to announce that the framework has reached feature completeness and is now ready for the masses. Lots of hours of work have been put into this project to make sure you have the best experience possible.
588
-
589
- ## 2024-09-23 - Jeasx 0.15.2 released
590
-
591
- Updates to all `@fastify-plugins, esbuild@0.24.0`
592
-
593
- ## 2024-09-21 - Jeasx 0.15.1 released
594
-
595
- Decorate the Fastify request object with `path` property, so you can easily access the route path without query parameters via request.path. This solves 99% of all use-cases for recently removed `@fastity/url-data`.
596
-
597
- ## 2024-09-20 - Jeasx 0.15.0 released
598
-
599
- This release comes with Fastify 5. It also removes `@fastify/url-data` and `@fastify/accepts` as dependencies, therefore your code might break. The reason behind this removal is to depend on less dependencies in the long run which makes maintenance of the core easier.
600
-
601
- If you rely on either accepts or url-data, you must provide appropriate changes in userland code. For `@fastify/url-data` I would recommend to use `fast-uri` and for `@fastify/accepts` `jshttp/accepts` for parsing accept-header if needed.
602
-
603
- Please note: there were some intermediate releases since the past proper release which shouldn't be used (and are mostly unpublished from npm).
604
-
605
- ## 2024-08-21 - Jeasx 0.11.2 released
606
-
607
- Added simple Dockerfile to quickstart template. Dependency updates: `esbuild@0.23.1, @fastify/cookie@9.4.0, @types/node@20.16.1`
608
-
609
- ## 2024-07-27 - Jeasx 0.11.1 released
610
-
611
- Performance optimization: if response is string or buffer, break evaluation loop early. This allows to build caches for pages and binary assets in userland.
612
-
613
- ## 2024-07-26 - Jeasx 0.11.0 released
614
-
615
- Updated to `jsx-async-runtime@0.5.0` which allows to override `jsxToString` from `jsx-async-runtime` to intercept / modify / replace JSX components via this context. Have a look at the example to see how it works.
616
-
617
- ## 2024-07-19 - Jeasx 0.10.1 released
618
-
619
- Breaking change: removed `@fastify/request-context` in favor of the recently introduced this context. Changing your code should be straightforward. This change decouples userland code from Fastify. Additionally code for Jeasx and `jsx-async-runtime` is provided unminified, so debugging and testing is far easier now.
620
-
621
- ## 2024-07-12 - Jeasx 0.9.1 released
622
-
623
- Updated to `jsx-async-runtime@0.4.1` which fixes a problem when running tests with Vitest.
624
-
625
- ## 2024-07-10 - Jeasx 0.9.0 released
626
-
627
- Updated to `jsx-async-runtime@0.4.0` which allows to use `this` as context object to avoid prop drilling. Have a look at the demo to see how things work.
628
-
629
- ## 2024-07-05 - Jeasx 0.8.0 released
630
-
631
- Updated to `jsx-async-runtime@0.3.0` (deprecated `renderToString` in favor of `jsxToString`)
632
-
633
- ## 2024-07-03 - Jeasx 0.7.6 released
634
-
635
- Updated to `esbuild@0.23.0`
636
-
637
- ## 2024-07-01 - Jeasx 0.7.5 released
638
-
639
- Updated to `fastify@4.28.1, esbuild@0.22.0, pm2@5.4.1`
640
-
641
- ## 2024-05-28 - Jeasx 0.7.4 released
642
-
643
- Updated to `esbuild@0.21.4, pm2@5.4.0`
644
-
645
- ## 2024-05-17 - Jeasx 0.7.3 released
646
-
647
- Updated to `esbuild@0.21.3, @types/node@20.12.12`
648
-
649
- ## 2024-05-08 - Jeasx 0.7.2 released
650
-
651
- Updated to `fastify@4.27.0, esbuild@0.21.1, @fastify/static@7.0.4`
652
-
653
- ## 2024-05-07 - Jeasx 0.7.1 released
654
-
655
- Updated `esbuild@0.21.0`
656
-
657
- ## 2024-04-27 - Jeasx 0.7.0 released
658
-
659
- This release introduces a new feature that allows you to post-process the resulting payloads, such as prettifying the HTML output. You can now set up a response handler, for example, in a guard. The response handler takes the resulting payload as a parameter and returns the modified payload.
660
-
661
- ```js
662
- import * as prettier from "prettier";
663
-
664
- export default function RootGuard({ request, reply }) {
665
- this.response = async (payload) => {
666
- return typeof payload === "string" &&
667
- String(reply.getHeader("content-type")).startsWith("text/html")
668
- ? await prettier.format(payload, { parser: "html" })
669
- : payload;
670
- };
671
- }
672
- ```
673
-
674
- Shame on me... I have recently started writing news as we approach the 1.0 release. But you can study the changelog at GitHub to see what has happend in the past.
675
-
676
- ## 2023-12-30 - First public commit
677
-
678
- Our Journey Begins! 🎉 Introducing Jeasx, a revolutionary web development framework born out of a summer experiment in 2023.
679
-
680
- Our mission?
681
-
682
- To simplify web development using server-rendered JSX as the cornerstone, bringing back the essence of the web: HTML, CSS, and progressive enhancing JavaScript. Join us as we redefine the future of web development together!