* Add task for cargo leptos w/ precompression
* Update makefile
* Update deps
* Serve precompressed assets
Code was taken from https://github.com/leptos-rs/cargo-leptos/pull/165#issuecomment-1647843037
Co-authored-by: Sebastian Dobe <sebastiandobe@mailbox.org>
* Dynamically compress html
* Update README
* Refactor: Format for ci
* Refactor: Replace use of format!
* Chore: Remove old build file
* Feat: Hash files
This will prevent users from using an old cached file after updates are made
* Fix: Prevent chicken & egg problem with target/site
* Refactor: Use normal cargo-leptos
---------
Co-authored-by: Sebastian Dobe <sebastiandobe@mailbox.org>
* docs: Add docs for `ToChildren`
As discussed in https://github.com/leptos-rs/leptos/discussions/2640,
the `ToChildren` trait is useful to consumers who want to use the
builder syntax. However, because it is currently annotated with
`#[docs(hidden)]`, it's not visible in docs and also not included in
Jetbrains's auto-complete.
Add a doc comment for the `ToChildren` trait, including doc tests that
demonstrate how to use the trait and how it compares to directly
creating children.
* docs: Fix incorrect examples in `ToChildren` docs
Some examples were added to `ToChildren` that don't compile. This
wasn't caught earlier because no errors were seen in the IDE when
writing the examples. The issue was correctly caught by CI, however.
* feat: Added initial dwarf debug counter example
* fix: update to readme and launch.json, task.json
* fix: fix tasks.json for debugging
* fix: added Trunk.toml to fix the port
* fix: moved example to projects
* Minor: examples/server_fns_axum FileWatcher logs errors to the console.
The cause is an assumption that the directory
./watched_files/
exits.
* chore: Now using .gitkeep to preserve directory structure.
* Add beginner tip to ErrorBoundary
This might seem simple, but the nuances of types and traits confuse many people learning the language.
* edit
* Update error_boundary.rs
* edits
* ignore error block
* Added name span to .build in component_to_tokens
* Added #[allow(unreachable_code)] to leptos::component_view inside component_to_tokens
* Added span to name reference in component_to_tokens
* Added span to leptos::component_props_builder in component_to_tokens
* Added span to props in component_to_tokens
* Added span to "on" method in events component_to_tokens
* Added spans in directive_call_from_attribute_node
* Added spans in fragment_to_tokens and it's ssr version
* Added span to props in slot_to_tokens
* Added span to the whole slot quote
* Changed slots's name span to last slot node
* Added span to the slot vec
* Added #[allow(unreachable_code)] to `.into()` in slot_to_tokens
* Added span to `.build()` in slot_to_tokens
* Added span for the whole component
* Added span to "clone:" directive
* Added span to ".children()"
* Removed unused "_span" param from fragment_to_tokens and fragment_to_tokens_ssr
* Removed unnecessary parenthesis around values in `attribute_to_tokens`
* Removed unnecessary curly braces around value in `spread_attrs`
* Removed unnecessary parenthesis around children in `element_to_tokens`
* Added catch-all span to element_to_tokens
* Formatted `quote!` according to official guidelines
* Updated view/snapshots in leptos_macro
* Added span to spread props in element_to_tokens_ssr
* Removed unnecessary curly braces in element_to_token_ssr
* Updated view/snapshots in leptos_macro
* Added view macro tests to leptos_macro
* Fixed clippy warnings in view macro output
* Updated view snapshots in tests
* Fixed expected_one_let_bind_got_none test in leptos_macro
* Removed snapshot tests in leptos_macro/tests/ui/view
---------
Co-authored-by: Greg Johnston <greg.johnston@gmail.com>
Manually reviewed the changes. All look like reasonable nudges.
A summary :-
In one place removed a redundant call to .clone().
In two places, now using clone_from() which clippy says
**MAY** be an optimisation.
It's normal to have a `NotFound` page with a wildcard path like this
```
<Routes>
...
<Route path="*any" view=NotFound>
</Routes>
```
In `ssr` mode, most servers do a `first match win` approach, so we
should register server functions before view routes, or else a wildcard
route would block all api requests.
https://discord.com/channels/1031524867910148188/1218508054442545185
Signed-off-by: 司芳源 <sify21@163.com>
non-serializable struct.
This prevents it from being returned in the
get_user() API, and prevents it from being unintentionally returned on any
new API the end-user may create on top of this example code.
Delegated event listeners do not support adding more than one event listener of the same type. This can cause confusion if two listeners are added, as one is silently dropped.
Instead of using `Closure::once_into_js`, this uses `into_js_value`,
which uses weak references to clean up the closure when Javascript no
longer has need of it.
It would be nice to make this (and the similar interval function) drop
the callback promptly when cancelled, but I don't think that's
possible while keeping the handles Copy.
Fixes#2330
Co-authored-by: Robert Macomber <robertm@mox>
In client-side navigation we now handle redirects returned from
server functions by resolving the location against the current
origin as a base. The base is only relevant if the location
doesn't already include an origin. This fixes cross-origin
redirects.
Note: in order to handle redirects in the same way as the browser
would handle them, we need to use the server function's URL
(typically `<origin>/api/something`) as a base. I leave this as
a TODO for a future leptos version, because it probably
requires changing the signature of the `server_fn` redirect hook.
In order to not be affected by a future breaking change, users
should already start making sure that their redirect locations
either include an origin or at least start with a single slash
(e.g. `Location: /foo`).
Otherwise user gets:
```
use_head() is being called without a MetaContext being provided. We'll automatically create and provide one, but if this is being called in a child route it may cause bugs. To be safe, you should provide_meta_context() somewhere in the root of the app.
```
* fix(ci): address clippy issue
* fix(ci): add missing nightly specifications
* fix(ci): set all nightly references
* chore(ci): do not lint example crates
Note that this is a minimal implementation and will __not__ allow the
user to `expect_state` if they have external calls to rendering their
app (i.e. using `render_app_to_*` directly).
This warning appears in the browser's console log.
```
hackernews.js:933 At src/routes/stories.rs:39:17, you are reading a resource in `hydrate` mode outside a <Suspense/> or <Transition/>. This can cause hydration mismatch errors and loses out on a significant performance optimization. To fix this issue, you can either:
1. Wrap the place where you read the resource in a <Suspense/> or <Transition/> component, or
2. Switch to using create_local_resource(), which will wait to load the resource until the app is hydrated on the client side. (This will have worse performance in most cases.)
```
This warning is seen in the browsers console window.
```
counter_isomorphic.js:1068 At src/counters.rs:138:17, you are reading a resource in `hydrate` mode outside a <Suspense/> or <Transition/>. This can cause hydration mismatch errors and loses out on a significant performance optimization. To fix this issue, you can either:
1. Wrap the place where you read the resource in a <Suspense/> or <Transition/> component, or
2. Switch to using create_local_resource(), which will wait to load the resource until the app is hydrated on the client side. (This will have worse performance in most cases.)
```
Two derived signals "value" and "error_msg" need to be wrapped in a <Suspense> block.
"value" falls back to just the initial text.
"error" uses the default fallback.
* chore: update to axum 0.7
Removed http, since it's included in axum, and replaced hyper by http-body-util, which is a smaller.
* chore: update samples to work with nre axum
Missing sessions_axum_auth, pending PR merge.
* chore: all dependencies update to axum 0.7
* chore: cargo fmt
* chore: fix doctests
* chore: Fix example that in reality doesn't use axum.
Fixed anyway.
* chore: more examples support for axum 0.7
* Small tweak
* retain trailing slashes in paths but leave matching trail-slash-insensitive
* fix: Allow trailing slashes to remain in leptos_path.
* Better handling for trailing slashes. (#2154)
This adds a trailing_slash option to <Router> and <Route>.
By default, this option is backward compatible with current Leptos
behavior, but users can opt into two new modes for handling trailing
slashes.
* cargo fmt
* Fix redirect routes for wildcard patterns.
* Clippy fixies
* (Re)Reduce the scope of PossibleBranchContext's internals.
* Test real code, not copied code.
* Test TrailingSlash redirects.
* Fixes and more tests for matching "" && "/".
This path is the exception to the rule and *should* be treated
as equivalent regardless of its trailing slash.
* cargo fmt
---------
Co-authored-by: Tadas Dailyda <tadas@dailyda.com>
The root cause is the family of leptos modules requiring both versions 0.10.5 and 0.11.0
This PR will fix that. ( Also needs a bump to 0.12.0 )
```
warning: multiple versions for dependency `itertools`: 0.10.5, 0.11.0
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions
note: the lint level is defined here
--> src/lib.rs:4:9
|
4 | #![warn(clippy::cargo)]
| ^^^^^^^^^^^^^
= note: `#[warn(clippy::multiple_crate_versions)]` implied by `#[warn(clippy::cargo)]`
```
// the `view` macro above expands to this builder syntax
div().child((
button().on(ev::click,clear).child("Clear"),
button().on(ev::click,decrement).child("-1"),
span().child(("Value: ",value,"!")),
button().on(ev::click,increment).child("+1")
))
}
// Easy to use with Trunk (trunkrs.dev) or with a simple wasm-bindgen setup
pubfnmain(){
mount_to_body(||view!{
@@ -131,7 +150,7 @@ There are several people in the community using Leptos right now for internal ap
### Can I use this for native GUI?
Sure! Obviously the `view` macro is for generating DOM nodes but you can use the reactive system to drive native any GUI toolkit that uses the same kind of object-oriented, event-callback-based framework as the DOM pretty easily. The principles are the same:
Sure! Obviously the `view` macro is for generating DOM nodes but you can use the reactive system to drive any native GUI toolkit that uses the same kind of object-oriented, event-callback-based framework as the DOM pretty easily. The principles are the same:
- Use signals, derived signals, and memos to create your reactive system
- Create GUI widgets
@@ -140,35 +159,27 @@ Sure! Obviously the `view` macro is for generating DOM nodes but you can use the
I've put together a [very simple GTK example](https://github.com/leptos-rs/leptos/blob/main/examples/gtk/src/main.rs) so you can see what I mean.
### How is this different from Yew/Dioxus?
The new rendering approach being developed for 0.7 supports “universal rendering,” i.e., it can use any rendering library that supports a small set of 6-8 functions. (This is intended as a layer over typical retained-mode, OOP-style GUI toolkits like the DOM, GTK, etc.) That future rendering work will allow creating native UI in a way that is much more similar to the declarative approach used by the web framework.
On the surface level, these libraries may seem similar. Yew is, of course, the most mature Rust library for web UI development and has a huge ecosystem. Dioxus is similar in many ways, being heavily inspired by React. Here are some conceptual differences between Leptos and these frameworks:
### How is this different from Yew?
Yew is the most-used library for Rust web UI development, but there are several differences between Yew and Leptos, in philosophy, approach, and performance.
- **VDOM vs. fine-grained:** Yew is built on the virtual DOM (VDOM) model: state changes cause components to re-render, generating a new virtual DOM tree. Yew diffs this against the previous VDOM, and applies those patches to the actual DOM. Component functions rerun whenever state changes. Leptos takes an entirely different approach. Components run once, creating (and returning) actual DOM nodes and setting up a reactive system to update those DOM nodes.
- **Performance:** This has huge performance implications: Leptos is simply much faster at both creating and updating the UI than Yew is. (Dioxus has made huge advances in performance with its recent 0.3 release, and is now roughly on par with Leptos.)
- **Mental model:** Adopting fine-grained reactivity also tends to simplify the mental model. There are no surprising component re-renders because there are no re-renders. You can call functions, create timeouts, etc. within the body of your component functions because they won’t be re-run. You don’t need to think about manual dependency tracking for effects; fine-grained reactivity tracks dependencies automatically.
- **Performance:** This has huge performance implications: Leptos is simply much faster at both creating and updating the UI than Yew is.
- **Server integration:** Yew was created in an erain which browser-rendered single-page apps (SPAs) were the dominant paradigm. While Leptos supports client-side rendering, it also focuses on integrating with the server side of your application via server functions and multiple modes of serving HTML, including out-of-order streaming.
### How is this different from Sycamore?
-### How is this different from Dioxus?
Conceptually, these two frameworks are very similar: because both are built on fine-grained reactivity, most apps will end up looking very similar between the two, and Sycamore or Leptos apps will both look a lot like SolidJS apps, in the same way that Yew or Dioxus can look a lot like React.
Like Leptos, Dioxus is a framework for building UIs using web technologies. However, there are significant differences in approach and features.
There are some practical differences that make a significant difference:
- **VDOM vs. fine-grained:** While Dioxus has a performant virtual DOM (VDOM), it still uses coarse-grained/component-scoped reactivity: changing a stateful value reruns the component function and diffs the old UI against the new one. Leptos components use a different mental model, creating (and returning) actual DOM nodes and setting up a reactive system to update those DOM nodes.
- **Web vs. desktop priorities:** Dioxus uses Leptos server functions in its fullstack mode, but does not have the same `<Suspense>`-based support for things like streaming HTML rendering, or share the same focus on holistic web performance. Leptos tends to prioritize holistic web performance (streaming HTML rendering, smaller WASM binary sizes, etc.), whereas Dioxus has an unparalleled experience when building desktop apps, because your application logic runs as a native Rust binary.
-**Templating:** Leptos uses a JSX-like template format (built on [syn-rsx](https://github.com/stoically/syn-rsx)) for its `view` macro. Sycamore offers the choice of its own templating DSL or a builder syntax.
- **Server integration:** Leptos provides primitives that encourage HTML streaming and allow for easy async integration and RPC calls, even without WASM enabled, making it easy to opt into integrations between your frontend and backend code without pushing you toward any particular metaframework patterns.
- **Read-write segregation:** Leptos, like Solid, encourages read-write segregation between signal getters and setters, so you end up accessing signals with tuples like `let (count, set_count) = create_signal(0);` _(If you prefer or if it's more convenient for your API, you can use [`create_rw_signal`](https://docs.rs/leptos/latest/leptos/fn.create_rw_signal.html) to give a unified read/write signal.)_
- **Signals are functions:** In Leptos, you can call a signal to access it rather than calling a specific method (so, `count()` instead of `count.get()`) This creates a more consistent mental model: accessing a reactive value is always a matter of calling a function. For example:
-### How is this different from Sycamore?
```rust
let (count, set_count) = create_signal(0); // a signal
let double_count = move || count() * 2; // a derived signal
let memoized_count = create_memo(move |_| count() * 3); // a memo
Sycamore and Leptos are both heavily influenced by SolidJS. At this point, Leptos has a larger community and ecosystem and is more actively developed. Other differences:
- **Signals and scopes are `'static`:** Both Leptos and Sycamore ease the pain of moving signals in closures (in particular, event listeners) by making them `Copy`, to avoid the `{ let count = count.clone(); move |_| ... }` that's very familiar in Rust UI code. Sycamore does this by using bump allocation to tie the lifetimes of its signals to its scopes: since references are `Copy`, `&'a Signal<T>` can be moved into a closure. Leptos does this by using arena allocation and passing around indices: types like `ReadSignal<T>`, `WriteSignal<T>`, and `Memo<T>` are actually wrappers for indices into an arena. This means that both scopes and signals are both `Copy` and `'static` in Leptos, which means that they can be moved easily into closures without adding lifetime complexity.
- **Templating DSLs:** Sycamore uses a custom templating language for its views, while Leptos uses a JSX-like template format.
- **`'static` signals:** One of Leptos’s main innovations was the creation of `Copy + 'static` signals, which have excellent ergonomics. Sycamore is in the process of adopting the same pattern, but this is not yet released.
- **Perseus vs. server functions:** The Perseus metaframework provides an opinionated way to build Sycamore apps that include server functionality. Leptos instead provides primitives like server functions in the core of the framework.
The examples in this directory are all built and tested against the current `main` branch.
To the extent that new features have been released or breaking changes have been made since the previous release, the examples are compatible with the `main` branch but not the current release.
To see the examples as they were at the time of the `0.5.0` release, [click here](https://github.com/leptos-rs/leptos/tree/v0.5.0/examples).
## Cargo Make
[Cargo Make](https://sagiegurari.github.io/cargo-make/) is used to build, test, and run examples.
Here are the highlights.
- Extendable custom task files are located in the [cargo-make](./cargo-make/) directory
- Running a task will automatically install `cargo` dependencies
- Each `Makefile.toml` file must extend the [cargo-make/main.toml](./cargo-make/main.toml) file
- [cargo-make](./cargo-make/) files that end in `*-test.toml` configure web testing strategies
- Run `cargo make test-report` to learn which examples have web tests
To the extent that new features have been released or breaking changes have been made since the previous release, the examples are compatible with the `main` branch and not the current release.
## Getting Started
The simplest way to get started with any example is to use the “quick start” command found in the README for each example. Most of the examples use either [`trunk`](https://trunkrs.dev/) (a simple build system and dev server for client-side-rendered apps) or [`cargo-leptos`](https://github.com/leptos-rs/cargo-leptos) (a build system for server-rendered and client-hydrated apps).
## Using Cargo Make
You can also run any of the examples using [`cargo-make`](https://github.com/sagiegurari/cargo-make). Note that this is completely optional. We use it for CI, and it can be convenient for running the examples, but is not required.
Follow these steps to get any example up and running.
1.`cd` to the example root directory
2.Run`cargomake ci` to setup and test the example
3.Run `cargo make start` to run the example
4.Open the client URL in the console output (<http://127.0.0.1:8080> or <http://127.0.0.1:3000> by default)
1.`cd` to the example you want to run
2.Make sure`cargo-make` is installed (for example by running `cargo install cargo-make`)
3.Make sure `rustup target add wasm32-unknown-unknown` was executed for the currently selected toolchain.
4.Run `cargo make ci` to setup and test the example
5. Run `cargo make start` to run the example
6. Open the client URL in the console output (<http://127.0.0.1:8080> or <http://127.0.0.1:3000> by default)
7. Run `cargo make stop` to end any processes started by `cargo make start`.
Here are a few additional notes:
- Extendable custom task files are located in the [cargo-make](./cargo-make/) directory
- Running a task will automatically install `cargo` dependencies
- Each `Makefile.toml` file must extend the [cargo-make/main.toml](./cargo-make/main.toml) file
- [cargo-make](./cargo-make/) files that end in `*-test.toml` configure web testing strategies
- Run `cargo make test-report` to learn which examples have web tests
# Defines a size-optimized profile for the WASM bundle in release mode
[profile.wasm-release]
inherits="release"
opt-level='z'
lto=true
codegen-units=1
panic="abort"
[package.metadata.leptos]
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
output-name="leptos_start"
# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup.
site-root="target/site"
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written
# Defaults to pkg
site-pkg-dir="pkg"
# [Optional] The source CSS file. If it ends with .sass or .scss then it will be compiled by dart-sass into CSS. The CSS is optimized by Lightning CSS before being written to <site-root>/<site-pkg>/app.css
style-file="style/main.scss"
# The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup.
site-addr="127.0.0.1:3000"
# The port to use for automatic reload monitoring
reload-port=3001
# [Optional] Command to use when running end2end tests. It will run in the end2end dir.
# [Windows] for non-WSL use "npx.cmd playwright test"
# This binary name can be checked in Powershell with Get-Command npx
end2end-cmd="npx playwright test"
end2end-dir="end2end"
# The browserlist query used for optimizing the CSS.
browserquery="defaults"
# Set by cargo-leptos watch when building with that tool. Controls whether autoreload JS will be included in the head
watch=false
# The environment Leptos will run in, usually either "DEV" or "PROD"
env="DEV"
# The features to use when compiling the bin target
#
# Optional. Can be over-ridden with the command line parameter --bin-features
bin-features=["ssr"]
# If the --no-default-features flag should be used when compiling the bin target
#
# Optional. Defaults to false.
bin-default-features=false
# The features to use when compiling the lib target
#
# Optional. Can be over-ridden with the command line parameter --lib-features
lib-features=["hydrate"]
# If the --no-default-features flag should be used when compiling the lib target
#
# Optional. Defaults to false.
lib-default-features=false
# The profile to use for the lib target when compiling for release
This is a template for use with the [Leptos](https://github.com/leptos-rs/leptos) web framework and the [cargo-leptos](https://github.com/akesson/cargo-leptos) tool.
## Creating your template repo
If you don't have `cargo-leptos` installed you can install it with
`cargo install cargo-leptos`
Then run
`cargo leptos new --git leptos-rs/start`
to generate a new project template (you will be prompted to enter a project name).
`cd {projectname}`
to go to your newly created project.
Of course, you should explore around the project structure, but the best place to start with your application code is in `src/app.rs`.
## Running your project
`cargo leptos watch`
By default, you can access your local project at `http://localhost:3000`
## Installing Additional Tools
By default, `cargo-leptos` uses `nightly` Rust, `cargo-generate`, and `sass`. If you run into any trouble, you may need to install one or more of these tools.
1.`rustup toolchain install nightly --allow-downgrade` - make sure you have Rust nightly
2.`rustup target add wasm32-unknown-unknown` - add the ability to compile Rust to WebAssembly
3.`cargo install cargo-generate` - install `cargo-generate` binary (should be installed automatically in future)
4.`npm install -g sass` - install `dart-sass` (should be optional in future)
## Executing a Server on a Remote Machine Without the Toolchain
After running a `cargo leptos build --release` the minimum files needed are:
1. The server binary located in `target/server/release`
2. The `site` directory and all files within located in `target/site`
Copy these files to your remote server. The directory structure should be:
```text
leptos_start
site/
```
Set the following environment variables (updating for your project as needed):
```sh
exportLEPTOS_OUTPUT_NAME="leptos_start"
exportLEPTOS_SITE_ROOT="site"
exportLEPTOS_SITE_PKG_DIR="pkg"
exportLEPTOS_SITE_ADDR="127.0.0.1:3000"
exportLEPTOS_RELOAD_PORT="3001"
```
Finally, run the server binary.
## Notes about CSR and Trunk:
Although it is not recommended, you can also run your project without server integration using the feature `csr` and `trunk serve`:
`trunk serve --open --features csr`
This may be useful for integrating external tools which require a static site, e.g. `tauri`.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.