dinou 2.3.3 → 2.4.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +120 -173
  3. package/cli.js +7 -6
  4. package/dinou/core/babel-esm-loader.js +100 -0
  5. package/dinou/{babel-esm-loader.js → core/get-abs-path-with-ext.js} +4 -95
  6. package/{react-refresh → dinou/react-refresh}/react-refresh-wrap-modules.js +0 -1
  7. package/{rollup-plugins → dinou/rollup-plugins}/dinou-asset-plugin.js +2 -2
  8. package/{rollup-plugins → dinou/rollup-plugins}/rollup-plugin-react-client-manifest.js +122 -40
  9. package/{rollup.config.js → dinou/rollup.config.js} +8 -8
  10. package/eject.js +7 -32
  11. package/package.json +13 -4
  12. /package/dinou/{asset-extensions.js → core/asset-extensions.js} +0 -0
  13. /package/dinou/{asset-require-hook.js → core/asset-require-hook.js} +0 -0
  14. /package/dinou/{build-static-pages.js → core/build-static-pages.js} +0 -0
  15. /package/dinou/{client-error.jsx → core/client-error.jsx} +0 -0
  16. /package/dinou/{client.jsx → core/client.jsx} +0 -0
  17. /package/dinou/{createScopedName.js → core/createScopedName.js} +0 -0
  18. /package/dinou/{generate-static-page.js → core/generate-static-page.js} +0 -0
  19. /package/dinou/{generate-static-pages.js → core/generate-static-pages.js} +0 -0
  20. /package/dinou/{generate-static-rsc.js → core/generate-static-rsc.js} +0 -0
  21. /package/dinou/{generate-static-rscs.js → core/generate-static-rscs.js} +0 -0
  22. /package/dinou/{generate-static.js → core/generate-static.js} +0 -0
  23. /package/dinou/{get-error-jsx.js → core/get-error-jsx.js} +0 -0
  24. /package/dinou/{get-file-path-and-dynamic-params.js → core/get-file-path-and-dynamic-params.js} +0 -0
  25. /package/dinou/{get-jsx.js → core/get-jsx.js} +0 -0
  26. /package/dinou/{get-ssg-jsx-or-jsx.js → core/get-ssg-jsx-or-jsx.js} +0 -0
  27. /package/dinou/{get-ssg-jsx.js → core/get-ssg-jsx.js} +0 -0
  28. /package/dinou/{get-static-paths.js → core/get-static-paths.js} +0 -0
  29. /package/dinou/{import-module.js → core/import-module.js} +0 -0
  30. /package/dinou/{register-loader.mjs → core/register-loader.mjs} +0 -0
  31. /package/dinou/{register-paths.js → core/register-paths.js} +0 -0
  32. /package/dinou/{render-app-to-html.js → core/render-app-to-html.js} +0 -0
  33. /package/dinou/{render-html.js → core/render-html.js} +0 -0
  34. /package/dinou/{render-jsx-to-client-jsx.js → core/render-jsx-to-client-jsx.js} +0 -0
  35. /package/dinou/{revalidating.js → core/revalidating.js} +0 -0
  36. /package/dinou/{server-function-proxy.js → core/server-function-proxy.js} +0 -0
  37. /package/dinou/{server.js → core/server.js} +0 -0
  38. /package/{postcss.config.js → dinou/postcss.config.js} +0 -0
  39. /package/{react-refresh → dinou/react-refresh}/esm-hmr/client.js +0 -0
  40. /package/{react-refresh → dinou/react-refresh}/esm-hmr/server.js +0 -0
  41. /package/{react-refresh → dinou/react-refresh}/is-react-refresh-boundary.js +0 -0
  42. /package/{react-refresh → dinou/react-refresh}/react-refresh-entry.js +0 -0
  43. /package/{react-refresh → dinou/react-refresh}/react-refresh-runtime.js +0 -0
  44. /package/{react-refresh → dinou/react-refresh}/rollup-plugin-esm-hmr.js +0 -0
  45. /package/{rollup-plugins → dinou/rollup-plugins}/rollup-plugin-server-functions.js +0 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [2.4.0]
9
+
10
+ ### Fixed
11
+
12
+ - rollup-plugin-react-client-manifest: now emits assets and csss correctly for server components.
13
+
14
+ ### Changed
15
+
16
+ - Now all folders and files ejected are grouped in dinou folder. What was before dinou folder now is dinou/core folder.
17
+ - README.md, updated.
18
+
8
19
  ## [2.3.3]
9
20
 
10
21
  ### Fixed
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # **dinou**: **A Minimal React 19 Framework**
1
+ # **Dinou**: **A React 19 Framework**
2
2
 
3
- [**dinou**](https://dinou.dev) is a **minimal React 19 framework**. dinou means 19 in Catalan. You can create a dinou [app](https://github.com/roggc/dinou-app) by running the command **`npx create-dinou@latest my-app`**.
3
+ [**Dinou**](https://dinou.dev) is a **React 19 framework**. "dinou" means 19 in Catalan. You can create a Dinou [app](https://github.com/roggc/dinou-app) by running the command **`npx create-dinou@latest my-app`**.
4
4
 
5
5
  Or you can create one by yourself with the following steps:
6
6
 
@@ -30,9 +30,9 @@ Or you can create one by yourself with the following steps:
30
30
 
31
31
  - Run `npm run dev` (or `npx dinou dev`) to see the page in action in your browser.
32
32
 
33
- - If you run `npm run eject` (or `npx dinou eject`), dinou will be ejected and copied to your root project folder, so you can customize it.
33
+ - If you run `npm run eject` (or `npx dinou eject`), Dinou will be ejected and copied to your root project folder, so you can customize it.
34
34
 
35
- dinou main features are:
35
+ Dinou main features are:
36
36
 
37
37
  - File-based routing system.
38
38
 
@@ -54,7 +54,7 @@ dinou main features are:
54
54
 
55
55
  - Support for the use of an import alias in `tsconfig.json` or `jsconfig.json` file.
56
56
 
57
- - Error handling with `error.tsx` pages, differentiationg behaviour in production and in development.
57
+ - Error handling with `error.tsx` pages, differentiating behaviour in production and in development.
58
58
 
59
59
  ## Table of contents
60
60
 
@@ -72,6 +72,8 @@ dinou main features are:
72
72
 
73
73
  - [Client Components](#client-components)
74
74
 
75
+ - [Server Functions](#server-functions)
76
+
75
77
  - [Dynamic Parameters (`params` prop)](#dynamic-parameters-params-prop)
76
78
 
77
79
  - [Query Parameters (`query` prop)](#query-parameters-query-prop)
@@ -114,9 +116,9 @@ dinou main features are:
114
116
 
115
117
  - [Import alias (e.g. `"@/..."`)](#import-alias-eg-)
116
118
 
117
- - [How to run a dinou app](#how-to-run-a-dinou-app)
119
+ - [How to run a Dinou app](#how-to-run-a-dinou-app)
118
120
 
119
- - [Eject dinou](#eject-dinou)
121
+ - [Eject Dinou](#eject-dinou)
120
122
 
121
123
  - [🚀 Deployment](#-deployment)
122
124
 
@@ -148,8 +150,11 @@ dinou main features are:
148
150
 
149
151
  ```typescript
150
152
  // src/dynamic/[name]/page_functions.ts
151
-
152
- export async function getProps(params: { name: string }) {
153
+ export async function getProps(
154
+ params: { name: string },
155
+ query: Record<string, string>,
156
+ cookies: Record<string, string>
157
+ ) {
153
158
  const data = await new Promise<string>((r) =>
154
159
  setTimeout(() => r(`Hello ${params.name}`), 2000)
155
160
  );
@@ -162,8 +167,11 @@ dinou main features are:
162
167
 
163
168
  ```typescript
164
169
  // src/dynamic/[name]/page_functions.ts
165
-
166
- export async function getProps(params: { name: string }) {
170
+ export async function getProps(
171
+ params: { name: string },
172
+ query: Record<string, string>,
173
+ cookies: Record<string, string>
174
+ ) {
167
175
  const data = await new Promise<string>((r) =>
168
176
  setTimeout(() => r(`Hello ${params.name}`), 2000)
169
177
  );
@@ -196,11 +204,10 @@ dinou main features are:
196
204
 
197
205
  - We have already seen that data can be fetched on the server with the `getProps` function or within the body of a Server Component, but this needs to be accompanied of a mechanism of SSG of the page/s to not increase the FCP.
198
206
 
199
- - There is an alternative that do not increase FCP even when rendering dynamically and that is to use `Suspense` for data fetching, either in the server and in the client.
207
+ - There is an alternative that do not increase FCP even when rendering dynamically and that is to use `Suspense` for data fetching, either in the server (in a Server Component) and in the client (in a Client Component).
200
208
 
201
209
  ```typescript
202
210
  // src/posts/post.tsx
203
-
204
211
  "use client";
205
212
 
206
213
  export type PostType = {
@@ -220,7 +227,6 @@ dinou main features are:
220
227
 
221
228
  ```typescript
222
229
  // src/posts/get-post.tsx
223
-
224
230
  "use server";
225
231
 
226
232
  import Post from "./post";
@@ -240,36 +246,41 @@ dinou main features are:
240
246
 
241
247
  ```typescript
242
248
  // src/posts/page.tsx
243
-
244
249
  "use client";
245
250
 
246
- import { Suspense } from "react";
251
+ import Suspense from "react-enhanced-suspense";
247
252
  import { getPost } from "./get-post";
248
- import Post from "./post";
249
- import type { PostType } from "./post";
250
253
 
251
- export default function Page({ data }: { data: string }) {
252
- const getPost2 = async () => {
253
- const post = await new Promise<PostType>((r) =>
254
- setTimeout(
255
- () => r({ title: "Post Title2", content: "Post content2" }),
256
- 1000
257
- )
258
- );
254
+ export default function Page() {
255
+ return (
256
+ <>
257
+ <Suspense fallback={<div>Loading...</div>} resourceId="get-post">
258
+ {() => getPost()}
259
+ </Suspense>
260
+ </>
261
+ );
262
+ }
263
+ ```
259
264
 
260
- return <Post post={post} />;
261
- };
265
+ - In Client Components, the `resourceId` prop together with passing a function to the `children` prop of `Suspense` from `react-enhanced-suspense` makes the promise returned by the Server Function stable between re-renders, and it is only reinvoked the Server Function whenever the `resourceId` changes.
266
+
267
+ - The same can be done with `page.tsx` being a Server Component. In that case we would not use the `resourceId` prop and we will call directly the Server Function:
268
+
269
+ ```typescript
270
+ // src/posts/page.tsx
271
+ import Suspense from "react-enhanced-suspense";
272
+ import { getPost } from "./get-post";
262
273
 
274
+ export default async function Page({ data }: { data: string }) {
263
275
  return (
264
276
  <>
265
277
  <Suspense fallback={<div>Loading...</div>}>{getPost()}</Suspense>
266
- <Suspense fallback={<div>Loading2...</div>}>{getPost2()}</Suspense>
267
278
  </>
268
279
  );
269
280
  }
270
281
  ```
271
282
 
272
- - The same can be done with `page.tsx` being a Server Component.
283
+ - `Suspense` from [react-enhanced-suspense](https://www.npmjs.com/package/react-enhanced-suspense) is React's `Suspense` when no extra prop is used.
273
284
 
274
285
  ## Fetching data in the server without `Suspense` (revisited)
275
286
 
@@ -285,7 +296,6 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
285
296
 
286
297
  ```typescript
287
298
  // src/catch-all-optional/[[..names]]/page.tsx
288
-
289
299
  "use client";
290
300
 
291
301
  export default function Page({
@@ -306,8 +316,11 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
306
316
 
307
317
  ```typescript
308
318
  // src/catch-all-optional/[[..names]]/page_functions.ts
309
-
310
- export async function getProps(params: { names: string[] }) {
319
+ export async function getProps(
320
+ params: { names: string[] },
321
+ query: Record<string, string>,
322
+ cookies: Record<string, string>
323
+ ) {
311
324
  const data = await new Promise<string>((r) =>
312
325
  setTimeout(() => r(`Hello ${params.names.join(",")}`), 2000)
313
326
  );
@@ -328,7 +341,6 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
328
341
 
329
342
  ```typescript
330
343
  // src/catch-all/[...names]/page.tsx
331
-
332
344
  "use client";
333
345
 
334
346
  export default function Page({
@@ -349,8 +361,11 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
349
361
 
350
362
  ```typescript
351
363
  // src/catch-all/[...names]/page_functions.ts
352
-
353
- export async function getProps(params: { names: string[] }) {
364
+ export async function getProps(
365
+ params: { names: string[] },
366
+ query: Record<string, string>,
367
+ cookies: Record<string, string>
368
+ ) {
354
369
  const data = await new Promise<string>((r) =>
355
370
  setTimeout(() => r(`Hello ${params.names.join(",")}`), 2000)
356
371
  );
@@ -371,7 +386,6 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
371
386
 
372
387
  ```typescript
373
388
  // src/optional/[[name]]/page.tsx
374
-
375
389
  "use client";
376
390
 
377
391
  export default function Page({
@@ -392,8 +406,11 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
392
406
 
393
407
  ```typescript
394
408
  // src/optional/[[name]]/page_functions.ts
395
-
396
- export async function getProps(params: { name: string }) {
409
+ export async function getProps(
410
+ params: { name: string },
411
+ query: Record<string, string>,
412
+ cookies: Record<string, string>
413
+ ) {
397
414
  const data = await new Promise<string>((r) =>
398
415
  setTimeout(() => r(`Hello ${params.name ?? ""}`), 2000)
399
416
  );
@@ -414,7 +431,6 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
414
431
 
415
432
  ```typescript
416
433
  // src/dynamic/[name]/page.tsx
417
-
418
434
  "use client";
419
435
 
420
436
  export default function Page({
@@ -435,8 +451,11 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
435
451
 
436
452
  ```typescript
437
453
  // src/dynamic/[name]/page_functions.ts
438
-
439
- export async function getProps(params: { name: string }) {
454
+ export async function getProps(
455
+ params: { name: string },
456
+ query: Record<string, string>,
457
+ cookies: Record<string, string>
458
+ ) {
440
459
  const data = await new Promise<string>((r) =>
441
460
  setTimeout(() => r(`Hello ${params.name}`), 2000)
442
461
  );
@@ -457,7 +476,6 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
457
476
 
458
477
  ```typescript
459
478
  // src/static/page.tsx
460
-
461
479
  "use client";
462
480
 
463
481
  export default function Page({ data }: { data: string }) {
@@ -467,8 +485,11 @@ Pages in **dynamic routes** (e.g. `/[id]`, or `/[[id]]`, `[...id]`, `[[...id]]`)
467
485
 
468
486
  ```typescript
469
487
  // src/static/page_functions.ts
470
-
471
- export async function getProps() {
488
+ export async function getProps(
489
+ params: Record<string, string>,
490
+ query: Record<string, string>,
491
+ cookies: Record<string, string>
492
+ ) {
472
493
  const data = await new Promise<string>((r) =>
473
494
  setTimeout(() => r(`data`), 2000)
474
495
  );
@@ -504,7 +525,11 @@ The framework supports a `page_functions.ts` (or `.tsx`, `.jsx`, `.js`) file in
504
525
  return ["1", "2", "3"];
505
526
  }
506
527
 
507
- export async function getProps(params: { id: string }) {
528
+ export async function getProps(
529
+ params: { id: string },
530
+ query: Record<string, string>,
531
+ cookies: Record<string, string>
532
+ ) {
508
533
  // Fetch data based on the 'id' parameter
509
534
  const post = await fetch(`https://api.example.com/posts/${params.id}`).then(
510
535
  (res) => res.json()
@@ -590,7 +615,23 @@ The framework supports a `page_functions.ts` (or `.tsx`, `.jsx`, `.js`) file in
590
615
 
591
616
  ## Client Components
592
617
 
593
- - Client components need to have the directive `"use client";` at the top of the file if they are not imported in other client components. That's the case of pages for example, that they are not imported directly in another client component. So when defining pages as client components **remember to use the directive `"use client";`**. The same applies for layouts, not found pages and error pages. In general, to avoid surprises, is a good practice to put the directive `"use client";` in all client components.
618
+ - Client Components need to have the directive `"use client";` at the top of the file if they are not imported in other Client Components. That's the case of pages for example, that they are not imported directly in another Client Component. So when defining pages as Client Components **remember to use the directive `"use client";`**. The same applies for layouts, not found pages and error pages. In general, to avoid surprises, is a good practice to put the directive `"use client";` in all Client Components.
619
+
620
+ ## Server Functions
621
+
622
+ - Server Functions are functions executed in the server. To define a Server Function use the directive `"use server";` at the top of the file where you define the Server Function. **Server Functions** can be invoked from either a Server Component or a Client Component and **can return Client Components**.
623
+
624
+ - You can access the `req` and `res` objects from express in the Server Function by adding an extra parameter in the definition, the last one:
625
+
626
+ ```typescript
627
+ "use server";
628
+
629
+ export async function doSomething(myParam, { req, res }) {
630
+ // ...
631
+ }
632
+ ```
633
+
634
+ - In the previous example, the Server Function should be called only with `myParam` as argument. The last argument with references to `req` and `res` from `express` is added by Dinou.
594
635
 
595
636
  ## Dynamic Parameters (`params` prop)
596
637
 
@@ -820,7 +861,7 @@ The routing system is file-based and supports static routes, dynamic routes, opt
820
861
  return (
821
862
  <html lang="en">
822
863
  <head>
823
- <title>dinou app</title>
864
+ <title>Dinou app</title>
824
865
  </head>
825
866
  <body>
826
867
  {sidebar}
@@ -933,7 +974,7 @@ export default function Layout({ children }: { children: ReactNode }) {
933
974
  return (
934
975
  <html lang="en">
935
976
  <head>
936
- <title>dinou app</title>
977
+ <title>Dinou app</title>
937
978
  <link rel="icon" type="image/png" href="/favicon.ico" />
938
979
  <link
939
980
  rel="apple-touch-icon"
@@ -964,7 +1005,7 @@ Then you will have your favicon in your web app.
964
1005
 
965
1006
  ## `.env` file
966
1007
 
967
- dinou is ready to manage env vars in the code that runs on the Server side (Server Functions, Server Components, and `getProps` function). Create an `.env` file in your project (and add it to your `.gitignore` file to not expose sensitive data to the public) and define there your env variables:
1008
+ Dinou is ready to manage env vars in the code that runs on the Server side (Server Functions, Server Components, and `getProps` function). Create an `.env` file in your project (and add it to your `.gitignore` file to not expose sensitive data to the public) and define there your env variables:
968
1009
 
969
1010
  ```bash
970
1011
  # .env
@@ -974,26 +1015,26 @@ MY_VAR=my_value
974
1015
 
975
1016
  ## Styles (Tailwind.css, .module.css, and .css)
976
1017
 
977
- dinou is ready to use Tailwind.css, `.module.css`, and `.css` styles. All styles will be generated in a file in `public` folder named `styles.css`. So you must include this in your `page.tsx` or `layout.tsx` file, in the `head` tag:
1018
+ Dinou is ready to use Tailwind.css, `.module.css`, and `.css` styles. All styles will be generated in a file in `public` folder named `styles.css`. So you must include this in your `page.tsx` or `layout.tsx` file, in the `head` tag:
978
1019
 
979
1020
  ```typescript
980
1021
  <link href="/styles.css" rel="stylesheet"></link>
981
1022
  ```
982
1023
 
983
- - Example with client components:
1024
+ - Example with Client Components (is the same for Server Components):
984
1025
 
985
1026
  ```typescript
986
1027
  // src/layout.tsx
987
1028
  "use client";
988
1029
 
989
1030
  import type { ReactNode } from "react";
990
- import "./global.css";
1031
+ import "./globals.css";
991
1032
 
992
1033
  export default function Layout({ children }: { children: ReactNode }) {
993
1034
  return (
994
1035
  <html lang="en">
995
1036
  <head>
996
- <title>dinou app</title>
1037
+ <title>Dinou app</title>
997
1038
  <link rel="icon" type="image/png" href="/favicon.ico" />
998
1039
  <link
999
1040
  rel="apple-touch-icon"
@@ -1022,7 +1063,7 @@ dinou is ready to use Tailwind.css, `.module.css`, and `.css` styles. All styles
1022
1063
  ```
1023
1064
 
1024
1065
  ```css
1025
- /* global.css */
1066
+ /* src/globals.css */
1026
1067
  @import "tailwindcss";
1027
1068
 
1028
1069
  .test1 {
@@ -1060,91 +1101,9 @@ dinou is ready to use Tailwind.css, `.module.css`, and `.css` styles. All styles
1060
1101
 
1061
1102
  - The above will produce the text `hi world!` in red, underlined, and with a purple background color.
1062
1103
 
1063
- - **Only styles imported under `"use client"` directive will be detected by dinou and generated in a `styles.css` in `public` folder**. This means that if you want to use server components instead of client components, then you must create an additional file (e.g. `styles.ts`) where you use the `"use client"` directive and import all the `.css` files used in server components.
1064
-
1065
- - Example with server components:
1066
-
1067
- ```typescript
1068
- // src/layout.tsx
1069
- import type { ReactNode } from "react";
1070
-
1071
- export default async function Layout({ children }: { children: ReactNode }) {
1072
- return (
1073
- <html lang="en">
1074
- <head>
1075
- <title>dinou app</title>
1076
- <link rel="icon" type="image/png" href="/favicon.ico" />
1077
- <link
1078
- rel="apple-touch-icon"
1079
- sizes="180x180"
1080
- href="/apple-touch-icon.png"
1081
- />
1082
- <link
1083
- rel="icon"
1084
- type="image/png"
1085
- sizes="32x32"
1086
- href="/favicon-32x32.png"
1087
- />
1088
- <link
1089
- rel="icon"
1090
- type="image/png"
1091
- sizes="16x16"
1092
- href="/favicon-16x16.png"
1093
- />
1094
- <link rel="manifest" href="/site.webmanifest"></link>
1095
- <link href="/styles.css" rel="stylesheet"></link>
1096
- </head>
1097
- <body>{children}</body>
1098
- </html>
1099
- );
1100
- }
1101
- ```
1102
-
1103
- ```css
1104
- /* global.css */
1105
- @import "tailwindcss";
1106
-
1107
- .test1 {
1108
- background-color: purple;
1109
- }
1110
- ```
1111
-
1112
- ```typescript
1113
- // src/page.tsx
1114
- import styles from "./page.module.css";
1115
-
1116
- export default async function Page() {
1117
- return (
1118
- <div className={`text-red-500 test1 ${styles.test2}`}>hi world!</div>
1119
- );
1120
- }
1121
- ```
1122
-
1123
- ```css
1124
- /* src/page.module.css */
1125
- .test2 {
1126
- text-decoration: underline;
1127
- }
1128
- ```
1129
-
1130
- ```typescript
1131
- // src/css.d.ts
1132
- declare module "*.module.css" {
1133
- const classes: { [key: string]: string };
1134
- export default classes;
1135
- }
1136
- ```
1137
-
1138
- ```typescript
1139
- // src/styles.ts
1140
- "use client"; // <-- This is key.
1141
- import "./global.css";
1142
- import "./page.module.css";
1143
- ```
1144
-
1145
1104
  ## Assets or media files (image, video, and sound)
1146
1105
 
1147
- dinou supports the use of assets in your components. Supported file extensions are: `.png`, `.jpeg`, `.jpg`, `.gif`, `.svg`, `.webp`, `.avif`, `.ico`, `.mp4`, `.webm`, `.ogg`, `.mov`, `.avi`, `.mkv`, `.mp3`, `.wav`, `.flac`, `.m4a`, `.aac`, `.mjpeg`, and `.mjpg`.
1106
+ Dinou supports the use of assets in your components. Supported file extensions are: `.png`, `.jpeg`, `.jpg`, `.gif`, `.svg`, `.webp`, `.avif`, `.ico`, `.mp4`, `.webm`, `.ogg`, `.mov`, `.avi`, `.mkv`, `.mp3`, `.wav`, `.flac`, `.m4a`, `.aac`, `.mjpeg`, and `.mjpg`.
1148
1107
 
1149
1108
  To use an asset in your component just import it as a default import:
1150
1109
 
@@ -1159,23 +1118,7 @@ export default function Component() {
1159
1118
  }
1160
1119
  ```
1161
1120
 
1162
- **Only assets imported under `"use client"` directive will be detected by dinou and generated in `public` folder**. If you use **server components**, then you must create an additional file (e.g. `assets.ts`) with the `"use client"` directive and import there the assets too:
1163
-
1164
- ```typescript
1165
- // src/assets.ts
1166
- "use client";
1167
-
1168
- import "./image.png";
1169
- ```
1170
-
1171
- ```typescript
1172
- // src/component.tsx
1173
- import image from "./image.png"; // import the image from where it is located (inside src folder)
1174
-
1175
- export default async function Component() {
1176
- return <img src={image} alt="image" />;
1177
- }
1178
- ```
1121
+ Works the same for Server Components.
1179
1122
 
1180
1123
  For typescript, you should create a declaration file like this:
1181
1124
 
@@ -1199,57 +1142,61 @@ declare module "*.png" {
1199
1142
  // and continue with the rest of supported file extensions
1200
1143
  ```
1201
1144
 
1202
- If you miss a certain file extension you can eject and customize dinou to meet your requirements. Just eject and add the extension in these three places: `rollup.config.js`, `dinou/server.js`, and `dinou/render-html.js`. Just look for the place were all the extensions are mentioned and add yours in these three files.
1145
+ If you miss a certain file extension you can eject and customize Dinou to meet your requirements. Just eject and add the extension in this place: `dinou/core/asset-extensions.js`. Just look for the place were all the extensions are mentioned and add yours in this file.
1203
1146
 
1204
1147
  ## Import alias (e.g. `"@/..."`)
1205
1148
 
1206
- dinou is ready to support import alias, as `import some from "@/..."`. If you want to use them just define the options in `tsconfig.json` or `jsconfig.json`:
1149
+ Dinou is ready to support import alias, as `import some from "@/..."`. If you want to use them just define the options in `tsconfig.json`:
1207
1150
 
1208
1151
  ```json
1209
- // tsconfig.json
1152
+ // tsconfig.json for a js project
1210
1153
  {
1211
1154
  "compilerOptions": {
1212
- // other options
1213
1155
  "baseUrl": ".",
1214
1156
  "paths": {
1215
1157
  "@/*": ["src/*"]
1216
- }
1158
+ },
1159
+ "allowJs": true,
1160
+ "noEmit": true
1217
1161
  },
1218
- "include": ["src/**/*"]
1219
- // other configuration fields
1162
+ "include": ["src"]
1220
1163
  }
1221
1164
  ```
1222
1165
 
1223
1166
  ```json
1224
- // jsconfig.json
1167
+ // tsconfig.json for a ts project
1225
1168
  {
1226
1169
  "compilerOptions": {
1227
1170
  "baseUrl": ".",
1228
1171
  "paths": {
1229
1172
  "@/*": ["src/*"]
1230
- }
1173
+ },
1174
+ "allowJs": true,
1175
+ "noEmit": true,
1176
+ "jsx": "react-jsx",
1177
+ "strict": true
1231
1178
  },
1232
1179
  "include": ["src"]
1233
1180
  }
1234
1181
  ```
1235
1182
 
1236
- ## How to run a dinou app
1183
+ ## How to run a Dinou app
1237
1184
 
1238
- Run `npm run dev` (or `npx dinou dev`) to start the dinou app in development mode. Wait for the logs of the bundler (`waiting for changes...`) and the server (`Listening on port <port>`) to load the page on your browser. In development, the bundler will emit its files in `public` folder.
1185
+ Run `npm run dev` (or `npx dinou dev`) to start the Dinou app in development mode. Wait for the logs of the bundler (`waiting for changes...`) and the server (`Listening on port 3000`) to load the page on your browser. In development, the bundler will emit its files in `public` folder.
1239
1186
 
1240
1187
  Run `npm run build` (or `npx dinou build`) to build the app and `npm start` (or `npx dinou start`) to run it. In production, the bundler will emit its files in `dist3` folder.
1241
1188
 
1242
- ## Eject dinou
1189
+ ## Eject Dinou
1243
1190
 
1244
- - You can eject dinou with the command `npm run eject` (or `npx dinou eject`). This will copy the files defining dinou in the root folder of the project (grouped in a `dinou` folder). You will have full control and customization capabilities.
1191
+ - You can eject Dinou with the command `npm run eject` (or `npx dinou eject`). This will copy the files defining Dinou in the root folder of the project (grouped in a `dinou` folder). You will have full control and customization capabilities.
1245
1192
 
1246
1193
  ## 🚀 Deployment
1247
1194
 
1248
- Projects built with **dinou** can be deployed to any platform that supports Node.js with custom flags.
1195
+ Projects built with **Dinou** can be deployed to any platform that supports Node.js with custom flags.
1249
1196
 
1250
1197
  ### ✅ Recommended: DigitalOcean App Platform
1251
1198
 
1252
- dinou works seamlessly on [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform). You can deploy your project easily without needing any special configuration.
1199
+ Dinou works seamlessly on [DigitalOcean App Platform](https://www.digitalocean.com/products/app-platform). You can deploy your project easily without needing any special configuration.
1253
1200
 
1254
1201
  **Why it works well:**
1255
1202
 
@@ -1261,9 +1208,9 @@ dinou works seamlessly on [DigitalOcean App Platform](https://www.digitalocean.c
1261
1208
 
1262
1209
  ### ❌ Not supported: Netlify
1263
1210
 
1264
- At the moment, **Netlify is not compatible with dinou, because it does not allow passing the `--conditions react-server` flag when starting a Node.js app**. This flag is essential for the app to work.
1211
+ At the moment, **Netlify is not compatible with Dinou, because it does not allow passing the `--conditions react-server` flag when starting a Node.js app**. This flag is essential for the app to work.
1265
1212
 
1266
- If Netlify adds support for custom runtime flags in the future, dinou compatibility might become possible.
1213
+ If Netlify adds support for custom runtime flags in the future, Dinou compatibility might become possible.
1267
1214
 
1268
1215
  ### 🛠 Other Platforms
1269
1216
 
@@ -1277,4 +1224,4 @@ For a detailed list of changes, enhancements, and bug fixes across versions, see
1277
1224
 
1278
1225
  ## License
1279
1226
 
1280
- dinou is licensed under the [MIT License](https://github.com/roggc/dinou/blob/master/LICENSE.md).
1227
+ Dinou is licensed under the [MIT License](https://github.com/roggc/dinou/blob/master/LICENSE.md).
package/cli.js CHANGED
@@ -6,6 +6,7 @@ const path = require("path");
6
6
  const { pathToFileURL } = require("url");
7
7
 
8
8
  const dinouPath = path.resolve(__dirname, "dinou");
9
+ const corePath = path.resolve(dinouPath, "core");
9
10
  const projectRoot = process.cwd();
10
11
 
11
12
  const runCommand = (command, options = {}) => {
@@ -23,10 +24,10 @@ program
23
24
  .action(() => {
24
25
  console.log("Starting...");
25
26
  const startExpress = `node --conditions react-server --import ${
26
- pathToFileURL(path.join(dinouPath, "register-loader.mjs")).href
27
- } ${path.join(dinouPath, "server.js")}`;
27
+ pathToFileURL(path.join(corePath, "register-loader.mjs")).href
28
+ } ${path.join(corePath, "server.js")}`;
28
29
  const startDevServer = `cross-env NODE_ENV=development rollup -c ${path.join(
29
- __dirname,
30
+ dinouPath,
30
31
  "rollup.config.js"
31
32
  )} -w`;
32
33
  runCommand(`npx concurrently "${startExpress}" "${startDevServer}"`);
@@ -37,7 +38,7 @@ program
37
38
  .description("Builds the app for production")
38
39
  .action(() => {
39
40
  console.log("Building the app...");
40
- const configPath = path.join(__dirname, "rollup.config.js");
41
+ const configPath = path.join(dinouPath, "rollup.config.js");
41
42
  runCommand(`cross-env NODE_ENV=production npx rollup -c ${configPath}`);
42
43
  });
43
44
 
@@ -48,8 +49,8 @@ program
48
49
  console.log("Starting the app...");
49
50
  runCommand(
50
51
  `cross-env NODE_ENV=production node --conditions react-server --import ${
51
- pathToFileURL(path.join(dinouPath, "register-loader.mjs")).href
52
- } ${path.join(dinouPath, "server.js")}`
52
+ pathToFileURL(path.join(corePath, "register-loader.mjs")).href
53
+ } ${path.join(corePath, "server.js")}`
53
54
  );
54
55
  });
55
56