jac-client 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl
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.
- jac_client/docs/README.md +50 -20
- jac_client/docs/advanced-state.md +13 -14
- jac_client/docs/asset-serving/intro.md +209 -0
- jac_client/docs/assets/pipe_line-v2.svg +32 -0
- jac_client/docs/file-system/app.jac.md +121 -0
- jac_client/docs/file-system/backend-frontend.md +217 -0
- jac_client/docs/file-system/intro.md +72 -0
- jac_client/docs/file-system/nested-imports.md +348 -0
- jac_client/docs/guide-example/intro.md +11 -13
- jac_client/docs/guide-example/step-01-setup.md +30 -20
- jac_client/docs/guide-example/step-02-components.md +24 -24
- jac_client/docs/guide-example/step-03-styling.md +24 -24
- jac_client/docs/guide-example/step-04-todo-ui.md +17 -17
- jac_client/docs/guide-example/step-05-local-state.md +23 -23
- jac_client/docs/guide-example/step-06-events.md +23 -24
- jac_client/docs/guide-example/step-07-effects.md +27 -28
- jac_client/docs/guide-example/step-08-walkers.md +23 -23
- jac_client/docs/guide-example/step-09-authentication.md +18 -18
- jac_client/docs/guide-example/step-10-routing.md +20 -21
- jac_client/docs/guide-example/step-11-final.md +34 -35
- jac_client/docs/imports.md +4 -5
- jac_client/docs/lifecycle-hooks.md +12 -13
- jac_client/docs/routing.md +21 -22
- jac_client/docs/styling/intro.md +249 -0
- jac_client/docs/styling/js-styling.md +367 -0
- jac_client/docs/styling/material-ui.md +341 -0
- jac_client/docs/styling/pure-css.md +299 -0
- jac_client/docs/styling/sass.md +403 -0
- jac_client/docs/styling/styled-components.md +395 -0
- jac_client/docs/styling/tailwind.md +298 -0
- jac_client/examples/all-in-one/.babelrc +9 -0
- jac_client/examples/all-in-one/README.md +16 -0
- jac_client/examples/all-in-one/app.jac +426 -0
- jac_client/examples/all-in-one/assets/burger.png +0 -0
- jac_client/examples/all-in-one/button.jac +7 -0
- jac_client/examples/all-in-one/components/button.jac +7 -0
- jac_client/examples/all-in-one/package.json +29 -0
- jac_client/examples/all-in-one/styles.css +26 -0
- jac_client/examples/all-in-one/vite.config.js +28 -0
- jac_client/examples/asset-serving/css-with-image/.babelrc +9 -0
- jac_client/examples/asset-serving/css-with-image/README.md +91 -0
- jac_client/examples/asset-serving/css-with-image/app.jac +88 -0
- jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
- jac_client/examples/asset-serving/css-with-image/package.json +28 -0
- jac_client/examples/asset-serving/css-with-image/styles.css +26 -0
- jac_client/examples/asset-serving/css-with-image/vite.config.js +28 -0
- jac_client/examples/asset-serving/image-asset/.babelrc +9 -0
- jac_client/examples/asset-serving/image-asset/README.md +119 -0
- jac_client/examples/asset-serving/image-asset/app.jac +55 -0
- jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
- jac_client/examples/asset-serving/image-asset/package.json +28 -0
- jac_client/examples/asset-serving/image-asset/styles.css +26 -0
- jac_client/examples/asset-serving/image-asset/vite.config.js +28 -0
- jac_client/examples/asset-serving/import-alias/.babelrc +9 -0
- jac_client/examples/asset-serving/import-alias/README.md +83 -0
- jac_client/examples/asset-serving/import-alias/app.jac +111 -0
- jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
- jac_client/examples/asset-serving/import-alias/package.json +28 -0
- jac_client/examples/asset-serving/import-alias/vite.config.js +28 -0
- jac_client/examples/basic/app.jac +14 -9
- jac_client/examples/basic/package.json +1 -1
- jac_client/examples/basic/vite.config.js +0 -1
- jac_client/examples/basic-auth/package.json +1 -1
- jac_client/examples/basic-auth/vite.config.js +0 -1
- jac_client/examples/basic-auth-with-router/package.json +1 -1
- jac_client/examples/basic-auth-with-router/vite.config.js +0 -1
- jac_client/examples/basic-full-stack/package.json +1 -1
- jac_client/examples/basic-full-stack/vite.config.js +0 -1
- jac_client/examples/css-styling/js-styling/.babelrc +9 -0
- jac_client/examples/css-styling/js-styling/README.md +183 -0
- jac_client/examples/css-styling/js-styling/app.jac +84 -0
- jac_client/examples/css-styling/js-styling/package.json +28 -0
- jac_client/examples/css-styling/js-styling/styles.js +100 -0
- jac_client/examples/css-styling/js-styling/vite.config.js +27 -0
- jac_client/examples/css-styling/material-ui/.babelrc +9 -0
- jac_client/examples/css-styling/material-ui/README.md +16 -0
- jac_client/examples/css-styling/material-ui/app.jac +122 -0
- jac_client/examples/css-styling/material-ui/package.json +32 -0
- jac_client/examples/css-styling/material-ui/vite.config.js +27 -0
- jac_client/examples/css-styling/pure-css/.babelrc +9 -0
- jac_client/examples/css-styling/pure-css/README.md +16 -0
- jac_client/examples/css-styling/pure-css/app.jac +64 -0
- jac_client/examples/css-styling/pure-css/package.json +28 -0
- jac_client/examples/css-styling/pure-css/styles.css +111 -0
- jac_client/examples/css-styling/pure-css/vite.config.js +27 -0
- jac_client/examples/css-styling/sass-example/.babelrc +9 -0
- jac_client/examples/css-styling/sass-example/README.md +16 -0
- jac_client/examples/css-styling/sass-example/app.jac +64 -0
- jac_client/examples/css-styling/sass-example/package.json +29 -0
- jac_client/examples/css-styling/sass-example/styles.scss +153 -0
- jac_client/examples/css-styling/sass-example/vite.config.js +27 -0
- jac_client/examples/css-styling/styled-components/.babelrc +9 -0
- jac_client/examples/css-styling/styled-components/README.md +16 -0
- jac_client/examples/css-styling/styled-components/app.jac +71 -0
- jac_client/examples/css-styling/styled-components/package.json +29 -0
- jac_client/examples/css-styling/styled-components/styled.js +90 -0
- jac_client/examples/css-styling/styled-components/vite.config.js +27 -0
- jac_client/examples/css-styling/tailwind-example/.babelrc +9 -0
- jac_client/examples/css-styling/tailwind-example/README.md +16 -0
- jac_client/examples/css-styling/tailwind-example/app.jac +63 -0
- jac_client/examples/css-styling/tailwind-example/global.css +1 -0
- jac_client/examples/css-styling/tailwind-example/package.json +30 -0
- jac_client/examples/css-styling/tailwind-example/vite.config.js +29 -0
- jac_client/examples/full-stack-with-auth/app.jac +20 -33
- jac_client/examples/full-stack-with-auth/package.json +1 -1
- jac_client/examples/full-stack-with-auth/vite.config.js +0 -1
- jac_client/examples/little-x/app.jac +327 -218
- jac_client/examples/little-x/submit-button.jac +1 -1
- jac_client/examples/nested-folders/nested-advance/.babelrc +9 -0
- jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +11 -0
- jac_client/examples/nested-folders/nested-advance/README.md +77 -0
- jac_client/examples/nested-folders/nested-advance/app.jac +35 -0
- jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +19 -0
- jac_client/examples/nested-folders/nested-advance/level1/Card.jac +43 -0
- jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +25 -0
- jac_client/examples/nested-folders/nested-advance/package.json +29 -0
- jac_client/examples/nested-folders/nested-advance/vite.config.js +28 -0
- jac_client/examples/nested-folders/nested-basic/.babelrc +9 -0
- jac_client/examples/nested-folders/nested-basic/README.md +183 -0
- jac_client/examples/nested-folders/nested-basic/app.jac +13 -0
- jac_client/examples/nested-folders/nested-basic/app.js +7 -0
- jac_client/examples/nested-folders/nested-basic/button.jac +7 -0
- jac_client/examples/nested-folders/nested-basic/components/button.jac +7 -0
- jac_client/examples/nested-folders/nested-basic/package.json +28 -0
- jac_client/examples/nested-folders/nested-basic/vite.config.js +27 -0
- jac_client/examples/with-router/app.jac +1 -1
- jac_client/examples/with-router/package.json +1 -1
- jac_client/examples/with-router/vite.config.js +0 -1
- jac_client/plugin/cli.py +7 -2
- jac_client/plugin/client.py +68 -5
- jac_client/plugin/client_runtime.jac +1 -1
- jac_client/plugin/vite_client_bundle.py +162 -14
- jac_client/tests/__init__.py +0 -1
- jac_client/tests/fixtures/basic-app/app.jac +7 -2
- jac_client/tests/fixtures/cl_file/app.cl.jac +48 -0
- jac_client/tests/fixtures/cl_file/app.jac +15 -0
- jac_client/tests/fixtures/client_app_with_antd/app.jac +14 -8
- jac_client/tests/fixtures/js_import/app.jac +19 -15
- jac_client/tests/fixtures/js_import/utils.js +0 -1
- jac_client/tests/fixtures/package.json +1 -1
- jac_client/tests/fixtures/relative_import/app.jac +4 -6
- jac_client/tests/fixtures/relative_import/button.jac +7 -6
- jac_client/tests/fixtures/spawn_test/app.jac +1 -5
- jac_client/tests/fixtures/test_fragments_spread/app.jac +24 -10
- jac_client/tests/test_asset_examples.py +322 -0
- jac_client/tests/test_cl.py +480 -426
- jac_client/tests/test_create_jac_app.py +125 -133
- jac_client/tests/test_it.py +329 -0
- jac_client/tests/test_nested_file.py +374 -0
- {jac_client-0.2.0.dist-info → jac_client-0.2.2.dist-info}/METADATA +2 -2
- jac_client-0.2.2.dist-info/RECORD +171 -0
- jac_client-0.2.0.dist-info/RECORD +0 -72
- {jac_client-0.2.0.dist-info → jac_client-0.2.2.dist-info}/WHEEL +0 -0
- {jac_client-0.2.0.dist-info → jac_client-0.2.2.dist-info}/entry_points.txt +0 -0
jac_client/docs/README.md
CHANGED
|
@@ -4,11 +4,41 @@ Welcome to the Todo App example! This guide will walk you through building a ful
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 1. Creating the Application
|
|
8
|
+
|
|
9
|
+
### Prerequisites
|
|
10
|
+
|
|
11
|
+
Before installing Jac client, you need to have **Node.js** installed on your system.
|
|
12
|
+
|
|
13
|
+
#### Installing Node.js
|
|
14
|
+
|
|
15
|
+
**For Linux users:**
|
|
16
|
+
|
|
17
|
+
Visit [https://nodejs.org/en/download](https://nodejs.org/en/download) and follow the instructions to install Node.js using **nvm** (Node Version Manager) with **npm**.
|
|
18
|
+
|
|
19
|
+
Select:
|
|
20
|
+
- **Platform**: Linux
|
|
21
|
+
- **Package Manager**: nvm
|
|
22
|
+
- **Package**: npm
|
|
23
|
+
|
|
24
|
+
Then follow the installation commands provided on that page.
|
|
25
|
+
|
|
26
|
+
**For macOS users:**
|
|
27
|
+
|
|
28
|
+
Download and install Node.js from [https://nodejs.org/en/download](https://nodejs.org/en/download) by selecting your operating system.
|
|
29
|
+
|
|
30
|
+
**Verify Installation:**
|
|
31
|
+
|
|
32
|
+
After installation, verify Node.js and npm are installed correctly:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
node -v
|
|
36
|
+
npm -v
|
|
37
|
+
```
|
|
8
38
|
|
|
9
39
|
### Installation
|
|
10
40
|
|
|
11
|
-
|
|
41
|
+
Once Node.js is installed, install the Jac client package:
|
|
12
42
|
|
|
13
43
|
```bash
|
|
14
44
|
pip install jac-client
|
|
@@ -53,7 +83,7 @@ You can access your app at `http://localhost:8000`
|
|
|
53
83
|
|
|
54
84
|
---
|
|
55
85
|
|
|
56
|
-
##
|
|
86
|
+
## 2. Entry Point of the App
|
|
57
87
|
|
|
58
88
|
Every Jac client application needs an entry point function. This is where your app starts rendering.
|
|
59
89
|
|
|
@@ -119,7 +149,7 @@ cl {
|
|
|
119
149
|
|
|
120
150
|
---
|
|
121
151
|
|
|
122
|
-
##
|
|
152
|
+
## 3. Creating Components
|
|
123
153
|
|
|
124
154
|
Components in Jac are functions that return JSX (JavaScript XML). They're similar to React components but written in pure Jac syntax.
|
|
125
155
|
|
|
@@ -194,7 +224,7 @@ def TodoItem(item: dict) -> any {
|
|
|
194
224
|
|
|
195
225
|
---
|
|
196
226
|
|
|
197
|
-
##
|
|
227
|
+
## 4. Adding State with React Hooks
|
|
198
228
|
|
|
199
229
|
Jac uses React hooks for state management. You can use all standard React hooks by importing them:
|
|
200
230
|
|
|
@@ -297,7 +327,7 @@ cl {
|
|
|
297
327
|
|
|
298
328
|
---
|
|
299
329
|
|
|
300
|
-
##
|
|
330
|
+
## 5. Event Handling
|
|
301
331
|
|
|
302
332
|
Event handling in Jac works just like React, but with Jac's lambda syntax.
|
|
303
333
|
|
|
@@ -385,7 +415,7 @@ def FilterButton(filterType: str, currentFilter: str, onFilterChange: any) -> an
|
|
|
385
415
|
|
|
386
416
|
---
|
|
387
417
|
|
|
388
|
-
##
|
|
418
|
+
## 6. Magic: No More Axios/Fetch!
|
|
389
419
|
|
|
390
420
|
One of Jac's most powerful features is **seamless backend communication** without writing HTTP requests, fetch calls, or axios code.
|
|
391
421
|
|
|
@@ -510,13 +540,13 @@ walker create_todo {
|
|
|
510
540
|
|
|
511
541
|
### Benefits of `spawn`
|
|
512
542
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
543
|
+
**No HTTP Configuration**: No need to set up API endpoints, CORS, or request/response formats
|
|
544
|
+
**Type Safety**: Jac handles serialization automatically
|
|
545
|
+
**Authentication**: Built-in token management via `jacLogin()` / `jacLogout()`
|
|
546
|
+
**Error Handling**: Exceptions are properly propagated
|
|
547
|
+
**Graph Operations**: Direct access to graph-based data operations
|
|
548
|
+
**Less Code**: Eliminates boilerplate HTTP client code
|
|
549
|
+
**Natural Syntax**: Call walkers on nodes using intuitive syntax
|
|
520
550
|
|
|
521
551
|
### Authentication Helpers
|
|
522
552
|
|
|
@@ -547,7 +577,7 @@ if jacIsLoggedIn() {
|
|
|
547
577
|
|
|
548
578
|
---
|
|
549
579
|
|
|
550
|
-
##
|
|
580
|
+
## Complete Example: Todo App Structure
|
|
551
581
|
|
|
552
582
|
Here's how all the pieces fit together:
|
|
553
583
|
|
|
@@ -612,7 +642,7 @@ cl {
|
|
|
612
642
|
|
|
613
643
|
---
|
|
614
644
|
|
|
615
|
-
##
|
|
645
|
+
## Running the Todo App
|
|
616
646
|
|
|
617
647
|
To run this example:
|
|
618
648
|
|
|
@@ -625,7 +655,7 @@ Then visit `http://localhost:8000` in your browser.
|
|
|
625
655
|
|
|
626
656
|
---
|
|
627
657
|
|
|
628
|
-
##
|
|
658
|
+
## Next Steps
|
|
629
659
|
|
|
630
660
|
Ready to dive deeper? Explore these advanced topics:
|
|
631
661
|
|
|
@@ -635,7 +665,7 @@ Ready to dive deeper? Explore these advanced topics:
|
|
|
635
665
|
- **[Imports](imports.md)**: Import third-party libraries (React, Ant Design, Lodash), other Jac files, and JavaScript modules
|
|
636
666
|
- **[Learn JAC](https://www.jac-lang.org)**: Explore Jac's graph-based data modeling
|
|
637
667
|
|
|
638
|
-
##
|
|
668
|
+
## Examples
|
|
639
669
|
|
|
640
670
|
Check out the `examples/` directory for working applications:
|
|
641
671
|
|
|
@@ -647,7 +677,7 @@ Check out the `examples/` directory for working applications:
|
|
|
647
677
|
|
|
648
678
|
---
|
|
649
679
|
|
|
650
|
-
##
|
|
680
|
+
## Key Takeaways
|
|
651
681
|
|
|
652
682
|
1. **Single Language**: Write frontend and backend in Jac
|
|
653
683
|
2. **No HTTP Client**: Use `spawn` syntax instead of fetch/axios
|
|
@@ -656,4 +686,4 @@ Check out the `examples/` directory for working applications:
|
|
|
656
686
|
5. **Type Safety**: Jac provides type checking across frontend and backend
|
|
657
687
|
6. **Graph Database**: Built-in graph data model eliminates need for SQL/NoSQL
|
|
658
688
|
|
|
659
|
-
Happy coding with Jac!
|
|
689
|
+
Happy coding with Jac!
|
|
@@ -4,7 +4,7 @@ Learn how to manage complex state in Jac using React hooks, combining multiple s
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Table of Contents
|
|
8
8
|
|
|
9
9
|
- [React Hooks Overview](#react-hooks-overview)
|
|
10
10
|
- [Multiple State Variables](#multiple-state-variables)
|
|
@@ -1091,7 +1091,7 @@ cl {
|
|
|
1091
1091
|
```jac
|
|
1092
1092
|
cl import from react { useState }
|
|
1093
1093
|
|
|
1094
|
-
#
|
|
1094
|
+
# Good: Separate state variables
|
|
1095
1095
|
def App() -> any {
|
|
1096
1096
|
let [user, setUser] = useState(None);
|
|
1097
1097
|
let [todos, setTodos] = useState([]);
|
|
@@ -1099,7 +1099,7 @@ def App() -> any {
|
|
|
1099
1099
|
let [theme, setTheme] = useState("light");
|
|
1100
1100
|
}
|
|
1101
1101
|
|
|
1102
|
-
#
|
|
1102
|
+
# Avoid: One giant state object for unrelated data
|
|
1103
1103
|
def App() -> any {
|
|
1104
1104
|
let [appState, setAppState] = useState({
|
|
1105
1105
|
"user": None,
|
|
@@ -1115,7 +1115,7 @@ def App() -> any {
|
|
|
1115
1115
|
```jac
|
|
1116
1116
|
cl import from react { useState, useMemo }
|
|
1117
1117
|
|
|
1118
|
-
#
|
|
1118
|
+
# Good: Memoize expensive calculations
|
|
1119
1119
|
def TodoApp() -> any {
|
|
1120
1120
|
let [todos, setTodos] = useState([]);
|
|
1121
1121
|
|
|
@@ -1124,7 +1124,7 @@ def TodoApp() -> any {
|
|
|
1124
1124
|
}, [todos]);
|
|
1125
1125
|
}
|
|
1126
1126
|
|
|
1127
|
-
#
|
|
1127
|
+
# Avoid: Computing on every render
|
|
1128
1128
|
def TodoApp() -> any {
|
|
1129
1129
|
let [todos, setTodos] = useState([]);
|
|
1130
1130
|
|
|
@@ -1138,13 +1138,13 @@ def TodoApp() -> any {
|
|
|
1138
1138
|
```jac
|
|
1139
1139
|
cl import from react { useState }
|
|
1140
1140
|
|
|
1141
|
-
#
|
|
1141
|
+
# Good: Calculate derived values
|
|
1142
1142
|
def TodoApp() -> any {
|
|
1143
1143
|
let [todos, setTodos] = useState([]);
|
|
1144
1144
|
activeCount = todos.filter(lambda t: any -> bool { return not t.done; }).length;
|
|
1145
1145
|
}
|
|
1146
1146
|
|
|
1147
|
-
#
|
|
1147
|
+
# Avoid: Storing derived values in state
|
|
1148
1148
|
def TodoApp() -> any {
|
|
1149
1149
|
let [todos, setTodos] = useState([]);
|
|
1150
1150
|
let [activeCount, setActiveCount] = useState(0); # Redundant!
|
|
@@ -1156,7 +1156,7 @@ def TodoApp() -> any {
|
|
|
1156
1156
|
```jac
|
|
1157
1157
|
cl import from react { useReducer }
|
|
1158
1158
|
|
|
1159
|
-
#
|
|
1159
|
+
# Good: useReducer for complex interdependent state
|
|
1160
1160
|
def TodoApp() -> any {
|
|
1161
1161
|
def reducer(state: dict, action: dict) -> dict {
|
|
1162
1162
|
if action.type == "ADD" {
|
|
@@ -1168,7 +1168,7 @@ def TodoApp() -> any {
|
|
|
1168
1168
|
let [state, dispatch] = useReducer(reducer, {"todos": [], "count": 0});
|
|
1169
1169
|
}
|
|
1170
1170
|
|
|
1171
|
-
#
|
|
1171
|
+
# Avoid: Multiple useState for interdependent state
|
|
1172
1172
|
def TodoApp() -> any {
|
|
1173
1173
|
let [todos, setTodos] = useState([]);
|
|
1174
1174
|
let [count, setCount] = useState(0);
|
|
@@ -1181,7 +1181,7 @@ def TodoApp() -> any {
|
|
|
1181
1181
|
```jac
|
|
1182
1182
|
cl import from react { useState, useEffect }
|
|
1183
1183
|
|
|
1184
|
-
#
|
|
1184
|
+
# Good: Comprehensive state management
|
|
1185
1185
|
def TodoApp() -> any {
|
|
1186
1186
|
let [todos, setTodos] = useState([]);
|
|
1187
1187
|
let [loading, setLoading] = useState(False);
|
|
@@ -1214,7 +1214,7 @@ def TodoApp() -> any {
|
|
|
1214
1214
|
```jac
|
|
1215
1215
|
cl import from react { useState, useCallback }
|
|
1216
1216
|
|
|
1217
|
-
#
|
|
1217
|
+
# Good: Memoized callbacks prevent unnecessary re-renders
|
|
1218
1218
|
def TodoApp() -> any {
|
|
1219
1219
|
let [todos, setTodos] = useState([]);
|
|
1220
1220
|
|
|
@@ -1234,7 +1234,7 @@ def TodoApp() -> any {
|
|
|
1234
1234
|
```jac
|
|
1235
1235
|
cl import from react { useState, useContext, createContext }
|
|
1236
1236
|
|
|
1237
|
-
#
|
|
1237
|
+
# Good: Context avoids prop drilling
|
|
1238
1238
|
ThemeContext = createContext("light");
|
|
1239
1239
|
|
|
1240
1240
|
def App() -> any {
|
|
@@ -1262,5 +1262,4 @@ def DeeplyNestedComponent() -> any {
|
|
|
1262
1262
|
- **Custom Hooks**: Create reusable state logic
|
|
1263
1263
|
- **Best Practices**: Separate concerns, avoid derived state, handle errors
|
|
1264
1264
|
|
|
1265
|
-
React hooks provide a powerful and flexible way to manage state in Jac applications!
|
|
1266
|
-
|
|
1265
|
+
React hooks provide a powerful and flexible way to manage state in Jac applications!
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Asset Serving in Jac
|
|
2
|
+
|
|
3
|
+
Static assets such as images, fonts, videos, and stylesheets are essential for web applications. Jac provides multiple approaches for serving these assets, each suited for different use cases.
|
|
4
|
+
|
|
5
|
+
!!! tip "Important"
|
|
6
|
+
All local assets must be placed in the `assets/` folder at the root of your project. The server serves these files from the `/static/` path.
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Jac supports two primary approaches for asset serving:
|
|
11
|
+
|
|
12
|
+
- **Remote Assets**: External URLs from CDNs or remote servers
|
|
13
|
+
- **Local Assets**: Files stored in your project, served by the Jac server
|
|
14
|
+
|
|
15
|
+
Local assets can be referenced using either **Static Path** (direct `/static/` URLs) or **Import Alias** (Vite-processed imports with optimization).
|
|
16
|
+
|
|
17
|
+
## Remote Assets
|
|
18
|
+
|
|
19
|
+
Use external URLs for assets hosted on CDNs or remote servers.
|
|
20
|
+
|
|
21
|
+
### Usage
|
|
22
|
+
|
|
23
|
+
```jac
|
|
24
|
+
<img src="https://picsum.photos/400/300" alt="Image" />
|
|
25
|
+
<img src="https://via.placeholder.com/400x300" alt="Placeholder" />
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### When to Use
|
|
29
|
+
|
|
30
|
+
- CDN-hosted production assets
|
|
31
|
+
- Placeholder images during development
|
|
32
|
+
- External resources managed outside your project
|
|
33
|
+
- Dynamic or user-generated content
|
|
34
|
+
|
|
35
|
+
## Local Assets
|
|
36
|
+
|
|
37
|
+
> **Important**: All local assets must be placed in the `assets/` folder at the root of your project. .
|
|
38
|
+
|
|
39
|
+
Local assets are stored in your project and served by the Jac server. Two methods are available:
|
|
40
|
+
|
|
41
|
+
### Static Path
|
|
42
|
+
|
|
43
|
+
Reference assets directly using the `/static/` path prefix.
|
|
44
|
+
|
|
45
|
+
#### Usage
|
|
46
|
+
|
|
47
|
+
```jac
|
|
48
|
+
<img src="/static/assets/burger.png" alt="Burger" />
|
|
49
|
+
<link rel="stylesheet" href="/static/styles.css" />
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
#### How It Works
|
|
53
|
+
|
|
54
|
+
- Assets in the `assets/` folder are served at `/static/assets/` path
|
|
55
|
+
- Assets in `dist/` are also accessible via `/static/`
|
|
56
|
+
- Server automatically detects file type and sets correct MIME type
|
|
57
|
+
- No build configuration required
|
|
58
|
+
|
|
59
|
+
#### When to Use
|
|
60
|
+
|
|
61
|
+
- Quick prototypes and simple applications
|
|
62
|
+
- Assets that don't require optimization
|
|
63
|
+
- Immediate results without build step
|
|
64
|
+
|
|
65
|
+
### Import Alias
|
|
66
|
+
|
|
67
|
+
Import assets using the `@jac-client/assets` alias for Vite-processed assets.
|
|
68
|
+
|
|
69
|
+
#### Usage
|
|
70
|
+
|
|
71
|
+
```jac
|
|
72
|
+
cl import from "@jac-client/assets/burger.png" { default as burgerImage }
|
|
73
|
+
|
|
74
|
+
<img src={burgerImage} alt="Burger" />
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
#### How It Works
|
|
78
|
+
|
|
79
|
+
- Alias configured in `vite.config.js` points to `src/assets/`
|
|
80
|
+
- Assets from root `assets/` folder are copied to `src/assets/` during build
|
|
81
|
+
- Vite processes imports and generates optimized asset URLs
|
|
82
|
+
- Automatic hash generation for cache busting
|
|
83
|
+
|
|
84
|
+
#### When to Use
|
|
85
|
+
|
|
86
|
+
- Production applications
|
|
87
|
+
- Assets that benefit from optimization
|
|
88
|
+
- Type-safe asset references
|
|
89
|
+
- Automatic cache busting
|
|
90
|
+
|
|
91
|
+
## Using Assets in CSS
|
|
92
|
+
|
|
93
|
+
Assets can be referenced in CSS files using static paths.
|
|
94
|
+
|
|
95
|
+
### Usage
|
|
96
|
+
|
|
97
|
+
**CSS File (`styles.css`):**
|
|
98
|
+
```css
|
|
99
|
+
.container {
|
|
100
|
+
background-image: url('/static/assets/burger.png');
|
|
101
|
+
background-size: cover;
|
|
102
|
+
background-position: center;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.burgerImage {
|
|
106
|
+
width: 200px;
|
|
107
|
+
height: auto;
|
|
108
|
+
border-radius: 10px;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Jac File:**
|
|
113
|
+
```jac
|
|
114
|
+
cl import "./styles.css";
|
|
115
|
+
|
|
116
|
+
<div className="container">
|
|
117
|
+
<img src="/static/assets/burger.png" className="burgerImage" alt="Burger" />
|
|
118
|
+
</div>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Notes
|
|
122
|
+
|
|
123
|
+
- CSS files reference assets using `/static/` paths
|
|
124
|
+
- Assets are resolved at runtime by the server
|
|
125
|
+
- Works with both background images and regular image elements
|
|
126
|
+
|
|
127
|
+
## Supported Asset Types
|
|
128
|
+
|
|
129
|
+
Jac automatically serves and detects MIME types for:
|
|
130
|
+
|
|
131
|
+
- **Images**: `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.svg`, `.ico`, `.avif`
|
|
132
|
+
- **Fonts**: `.woff`, `.woff2`, `.ttf`, `.otf`, `.eot`
|
|
133
|
+
- **Media**: `.mp4`, `.webm`, `.ogg`, `.mov`, `.mp3`, `.wav`, `.m4a`
|
|
134
|
+
- **Documents**: `.pdf`
|
|
135
|
+
- **Stylesheets**: `.css`, `.scss`, `.sass`, `.less`
|
|
136
|
+
|
|
137
|
+
## Project Structure
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
project/
|
|
141
|
+
├── assets/ # Static assets (served via /static/)
|
|
142
|
+
│ ├── images/
|
|
143
|
+
│ ├── fonts/
|
|
144
|
+
│ └── videos/
|
|
145
|
+
├── src/
|
|
146
|
+
│ └── assets/ # Assets for import alias (@jac-client/assets)
|
|
147
|
+
└── dist/ # Vite output (auto-generated)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Examples
|
|
151
|
+
|
|
152
|
+
Complete working examples are available:
|
|
153
|
+
|
|
154
|
+
- [`image-asset/`](../../examples/asset-serving/image-asset/) - Static path serving
|
|
155
|
+
- [`import-alias/`](../../examples/asset-serving/import-alias/) - Import alias pattern
|
|
156
|
+
- [`css-with-image/`](../../examples/asset-serving/css-with-image/) - Assets in CSS
|
|
157
|
+
|
|
158
|
+
Run any example:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
cd jac-client/jac_client/examples/asset-serving/<example-name>
|
|
162
|
+
npm install
|
|
163
|
+
jac serve app.jac
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Quick Reference
|
|
167
|
+
|
|
168
|
+
### Remote URLs
|
|
169
|
+
```jac
|
|
170
|
+
<img src="https://example.com/image.jpg" alt="Image" />
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Static Path
|
|
174
|
+
```jac
|
|
175
|
+
<img src="/static/assets/logo.png" alt="Logo" />
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Import Alias
|
|
179
|
+
```jac
|
|
180
|
+
cl import from "@jac-client/assets/logo.png" { default as logo }
|
|
181
|
+
<img src={logo} />
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### CSS Assets
|
|
185
|
+
```css
|
|
186
|
+
.hero {
|
|
187
|
+
background-image: url('/static/assets/hero.jpg');
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Troubleshooting
|
|
192
|
+
|
|
193
|
+
**Asset not found (404)**
|
|
194
|
+
- Verify file exists in `assets/` or `dist/` directory
|
|
195
|
+
- Check path matches file location exactly
|
|
196
|
+
|
|
197
|
+
**Import not resolving**
|
|
198
|
+
- Ensure `vite.config.js` has `@jac-client/assets` alias configured
|
|
199
|
+
- Verify assets are copied to `src/assets/` during build
|
|
200
|
+
|
|
201
|
+
**CSS background image not showing**
|
|
202
|
+
- Use `/static/` prefix in CSS `url()` paths
|
|
203
|
+
- Verify asset file exists in `assets/` directory
|
|
204
|
+
|
|
205
|
+
## Related Documentation
|
|
206
|
+
|
|
207
|
+
- [Import System](../imports.md)
|
|
208
|
+
- [Styling](../styling/intro.md)
|
|
209
|
+
- [Routing](../routing.md)
|