trunk-rs / trunk Goto Github PK
View Code? Open in Web Editor NEWBuild, bundle & ship your Rust WASM application to the web.
Home Page: https://trunkrs.dev/
License: Apache License 2.0
Build, bundle & ship your Rust WASM application to the web.
Home Page: https://trunkrs.dev/
License: Apache License 2.0
Per the discussion over here #46 (comment), it would seem that Trunk needs to do a better job at determining the name of the output WASM. Let's leverage cargo-metadata as much as possible to handle edge cases like this.
This should be a simple matter of checking the package's targets (already provided by cargo-metadata), and then checking to ensure that there is only 1 bin. In the future, as we move to complete #46, we will support multiple bins, where one is the app, and others are workers.
Lots of discussion to be had here. The main idea is that we want a trunk test
command which will do the right thing in terms of running unit tests, integration tests &c.
A few ideas were being tossed around on the Yew community Discord. Right now, I am definitely leaning towards leveraging wasm-pack test
as much as possible. It already handles a lot of the heavy lifting.
Currently, this issue is in discussion phase. We need to determine what would be best for users.
How can I change the init script location in index.html
?
(Is it possible? Did I overlook something in README?)
Input:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<section id="app"></section>
<trunk-link type="rust">
</body>
</html>
(I've copy-pasted trunk-link
from #46)
Expected output:
...
<body>
<section id="app"></section>
<script type="module">
import init from '/index-719b4e04e016028b.js';
init('/index-719b4e04e016028b_bg.wasm');
</script>
</body>
...
Thanks!
An idea: $ trunk
would be an alias for $ trunk serve
.
Motivation: I think trunk serve
will be the most used command. Also it would reduce cognitive load a little bit because I don't need to remember command serve
(otherwise I can imagine I would often accidentally write its equivalent from other tools like server
or start
). And it's a redundant command because of standard -h
/ --help
Probably use https://github.com/rust-analyzer/expect-test
How can I change the init script location in index.html
?
(Is it possible? Did I overlook something in README?)
Input:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<section id="app"></section>
<trunk-link type="rust">
</body>
</html>
(I've copy-pasted trunk-link
from #46)
Expected output:
...
<body>
<section id="app"></section>
<script type="module">
import init from '/index-719b4e04e016028b.js';
init('/index-719b4e04e016028b_bg.wasm');
</script>
</body>
...
Thanks!
It would be great to have the ability to specify cargo feature flags for the internal invocation of cargo build
.
Maybe it would even make more sense to make this even more generic and pass any number of arguments to the cargo invocation, as this would also cover other flags like "--no-default-features" etc., which otherwise have to be manually mirrored.
One thing I have noticed with trunk 0.6.0 that running build
in a subdirectory will place the dist
directory now in the parent directory.
I wonder if this is desired behaviour since I remember that before it was placed in the directory the command was run in?
cargo install trunk
-> error.
cargo install --git https://github.com/thedodd/trunk.git
-> error.
Using latest Rust and OS.
I do not know why it tries to compile surf v2.0.0-alpha.6
when in Cargo.lock has surf-v2.0.0-alpha.5
โฏ cargo install trunk
Updating crates.io index
Installing trunk v0.5.1
Compiling async-sse v4.0.0
Compiling markup5ever v0.10.0
Compiling surf v2.0.0-alpha.6
error[E0453]: allow(explicit_outlives_requirements) overruled by outer forbid(rust_2018_idioms)
--> /Users/fbucek/.cargo/registry/src/github.com-1ecc6299db9ec823/async-sse-4.0.0/src/encoder.rs:9:1
|
9 | / pin_project_lite::pin_project! {
10 | | /// An SSE protocol encoder.
11 | | #[derive(Debug)]
12 | | pub struct Encoder {
... |
17 | | }
18 | | }
| |_^ overruled by previous forbid
|
::: /Users/fbucek/.cargo/registry/src/github.com-1ecc6299db9ec823/async-sse-4.0.0/src/lib.rs:34:11
|
34 | #![forbid(rust_2018_idioms)]
| ---------------- `forbid` level set here
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0453]: allow(explicit_outlives_requirements) overruled by outer forbid(rust_2018_idioms)
--> /Users/fbucek/.cargo/registry/src/github.com-1ecc6299db9ec823/async-sse-4.0.0/src/lines.rs:11:1
|
11 | / pin_project! {
12 | | /// A stream of lines in a byte stream.
13 | | ///
14 | | /// This stream is created by the [`lines`] method on types that implement [`BufRead`].
... |
28 | | }
29 | | }
| |_^ overruled by previous forbid
|
::: /Users/fbucek/.cargo/registry/src/github.com-1ecc6299db9ec823/async-sse-4.0.0/src/lib.rs:34:11
|
34 | #![forbid(rust_2018_idioms)]
| ---------------- `forbid` level set here
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0453]: allow(explicit_outlives_requirements) overruled by outer forbid(rust_2018_idioms)
--> /Users/fbucek/.cargo/registry/src/github.com-1ecc6299db9ec823/surf-2.0.0-alpha.6/src/response.rs:17:1
|
17 | / pin_project_lite::pin_project! {
18 | | /// An HTTP response, returned by `Request`.
19 | | pub struct Response {
20 | | #[pin]
21 | | res: http_client::Response,
22 | | }
23 | | }
| |_^ overruled by previous forbid
|
::: /Users/fbucek/.cargo/registry/src/github.com-1ecc6299db9ec823/surf-2.0.0-alpha.6/src/lib.rs:73:11
|
73 | #![forbid(rust_2018_idioms)]
| ---------------- `forbid` level set here
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0453`.
error: could not compile `async-sse`.
To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: aborting due to previous error
For more information about this error, try `rustc --explain E0453`.
error: failed to compile `trunk v0.5.1`, intermediate artifacts can be found at `/Users/fbucek/_temp_/rust-target`
Caused by:
build failed
In ParcelJS, the JS import system is overloaded to allow users to "import" images, css, sass and the like into their JS, and then Parcel will intercept those non-JS imports and build/bundle/hash them. It would be awesome to do something similar for trunk.
Create a compile-time macro which will take a path to a resource, maybe a few config options as well. Something like trunk::include!("assets/my-image.png")
, or trunk::include!("my-component.css", Opt::Hash, Opt::Compress)
.
trunk::include!("src/**/*.css")
, to spawn pipelines for, and include, all css files under the src
dir. A similar pattern is already planned as part of #3. Will probably support both.A variant of the macro will be exported, say trunk::include_ref!(...)
, which will return a String value which will be the public url of the asset, hashed and all, once the trunk pipeline is complete. This will allow applications to include an image directly in their Rust source code and have a correct ref to the asset after hashing and all.
cargo build
is executed outside of the context of trunk./<asset>
or /static/<asset>
&c)./
as the base path of the asset, but users will be able to set an env var to overwrite the default. When cargo is invoked by trunk during a trunk build
(which is how all of this is intended to be used), trunk will be able to set the env var based on the value of --public-url
to coordinate the values.Definitely open to other design options here. Please comment and let me know if you've got ideas you would like to share.
hi
I have a yew project with npm package material-components-web
as a dependency.
now I use parcel to build the project.
Does trunk support this dependency management?
thx
index.html
file is served as a fallback.trunk config show
command output with some snapshot tests to ensure Trunk.toml
and env vars are processed properly.--help
output to ensure we don't hit a regression in CLI help output.trunk
does not work with multi-package projects. I tested this with a project with frontend
and backend
packages under the main app package. Running trunk build
in frontend
resulted in it failing with the following error message
$ trunk build
๐ฆ starting cargo build on frontend
๐ฆ spawning asset pipelines
could not read file `chatr/frontend/target/wasm32-unknown-unknown/debug/frontend.wasm`
It looks like it is trying to create target
directory in frontend
package when it should be using the main app's directory.
This renders trunk
unusable for multi-package projects
Currently, trunk
ships with a built-in scss/sass compiler (https://github.com/compass-rs/sass-rs). We definitely need to add support for additional asset types.
<link data-trunk rel="css-components"/>
any CSS found in the source tree will be concatenated & bundled, which would enable a nice zero-config "component styles" pattern. Users would be able to just create a CSS file right next to their Rust components, and Trunk will automatically process & bundle it.There are probably plenty of other asset types the community will want to support. Let's talk about them here, and then create specific issues for each asset type when we are ready to build the plugin/pipeline system.
cargo publish
.This primarily applies to:
trunk serve
shows the line listening at http://0.0.0.0:8080
and opens a new browser tab with url http://localhost:8080/
.
localhost
but 127.0.0.1
. (It's often useful for performance testing because it eliminates slow DNS.)127.0.0.1
.192.168.x.x
.trunk serve
in a CI environment (you may want it as a part of a custom test/prerender pipeline).Suggested changes:
trunk serve --open
.listening at http://0.0.0.0:8080
to something like listening on port 8080 (http://localhost:8080)
. That way it should be clear that the server is bonded to multiple IPs and users can open manually a new browser tab with localhost
quickly by clicking on the url (if the user's IDE is smart enough to transform urls in the terminal to clickable links.).Prerendering is important for SEO & SMO, website performance and it allows to use Rust frameworks as static site generators.
Seed templates use react-snap as a non-Rust prerendering tool.
I think we can assume that wasm-bindgen
automatically downloads needed webdrivers and there is a browser already installed on the target platform to make testing possible.
So we should be able to implement prerendering using one of these crates:
Per some discussion here https://discordapp.com/channels/701068342760570933/701068343431528490/748623604563837030 it looks like we may be able to move away from requiring folks to use the #[wasm_bindgen(start)]
attribute.
Also see rustwasm/wasm-bindgen#1057 (comment)
fn main
without the #[wasm_bindgen(start)]
attribute.SPAs with routing support need to know their base URL to work properly. Many apps just have this hard-coded or alternatively use the naive assumption that the app is hosted at the root.
Trunk already has the --public-url
flag which allows users to specify the base URL of the app, but so far this is only used by Trunk and isn't exposed to the app.
If the base URL is hard-coded into the app and it doesn't match the given public URL, things stop working properly.
One way to solve this is to make it possible for Trunk to insert a <base>
tag with the public URL.
This can be opt-in (Though note that any app that uses some form of routing should make use of this):
<head>
<base href="trunk-public-dir" />
</head>
At runtime, this value can be accessed easily using document.baseURI
.
This approach is so flexible that I can imagine adding support for it to yew-router
which would mean that any app using it works regardless of the --public-url
we pass in.
Not sure about you, but that sounds very exciting to me!
I chose the <base>
element instead of another approach like adding a data-public-url
to the <html>
element mainly because it already has the appropriate semantics for this.
It will change the behaviour of relative URLs to be relative to the public URL instead of the current location. We've noticed that many users try to use relative URLs when using routing for the first time so this actually seems to be the more intuitive behaviour.
That being said, I really don't mind using a different approach either. All that really matters is that we have access to it.
Shout-out to @MartinKavik for the report on this one as well. This will definitely be an improvement.
Looks like all Seed and Yew templates have
index.html
in the root or in other directories like static. So I would suggest to write onlyindex.html
to README and also try it as the first option if the parameter isn't provided.
~ Martin
Yes, definitely agree on the above. Will do.
index.html
.trunk
, while serving content, should auto refresh the page when serving like how basically every other bundler does.
Currently, the development server spawned with trunk serve
doesn't allow proxying requests. This renders it mostly useless as API calls to backend can't be made from the app served by the development server.
Most likely we should just use https://github.com/mitsuhiko/indicatif & https://github.com/mitsuhiko/console.
Mainly I would like to establish a standard for how we output content to the shell.
build complete
message when the full build/bundle/pipeline is finished. (thanks Martin)Otherwise cargo install trunk
breaks on Windows.
A few things to consider here:
Per some discussion with @ashleygwilliams, there is a strong possibility that we will be able to leverage the excellent wasm-pack
project to handle some other aspects of the build pipeline, and ensuring that certain dependencies are in place and matching correctly.
Take a look at:
May be able to just add wasm-pack to the trunk Cargo.toml and leverage the code that way. Time to test this out! Thanks Ashley for chatting about this and tossing ideas around!
Example:
mkdir empty_dir
cd empty_dir
trunk build
echo $?
prints 0
Expected any non-zero value.
trunk build
obviously fails in an empty directory but the exit code is still 0.
Exit code is helpful to short-circuit a build pipeline if the "trunk build" step fails but without non-zero return code it is non-trivial to do.
P.S. Thanks for the awesome tool!
This is a continuation of #33
Currently this is blocked on upstream support for WebSockets in Tide.
Currently, the progress system does well at indicating that work is being done, but the text only shows the very last item to be started.
My reference for this issue is Yew's multi_thread
example which requires two WASM binaries. One for the actual application and one for the Web Worker.
Up until now building applications with web workers has been a real pain but with trunk we have the chance to turn this around.
The following is an objective list of problems that need to be solved to support Web Workers.
Trunk should handle crates with multiple binary targets gracefully.
Currently, invoking trunk serve
on the aforementioned example results in this error:
could not read file `$TARGET/wasm32-unknown-unknown/debug/multi_thread.wasm`
๐ก server running at http://127.0.0.1:8080/
โ build finished with errors
The multi_thread.wasm
could not be found because there are two WASM binaries called app.wasm
and worker.wasm
.
While it isn't strictly related to this issue, I think this behaviour could be improved.
Because of how Web Worker are created[link] we need to know the URL of the worker's Javascript file while compiling the app.
Trunk currently runs wasm-bindgen
with --target=web
. The generated js code exports an initializer function which needs to be called to start the program. This doesn't work for Web Workers as they need to be self-executing.
This is just one potential way of solving the issues mentioned above to get the discussion started.
Since Trunk already has a config file, I think it makes perfect sense to use it for this.
We add a new section to [build]
, let's call it "targets", which is used to configure binary targets.
To take care of 3., we can simply build the WASM with --target=no-modules
.
Since we still want to have normal binaries, let's give each target a type
key with the following two values:
--target=web
and includes it in index.html
.--target=no-modules
.dist/
but not added to index.html
For 2. we need to allow targets to side-step hashing so we can assign static URLs to them.
In the future this could use a similar approach to #9 so we don't miss out on caching, but for now we can just add a key "output" to the target which manually sets the output path.
This is what it would look like when applied to the multi_thread
example:
[build.targets.app]
type = "script"
[build.targets.worker]
type = "worker"
output = "worker.js"
Trunk should reject projects with multiple binaries (without appropriate configuration) outright and point the user to documentation on the subject.
It might be tempting to guess which binary is which based on certain keywords (like "app" and "worker") but this probably does more harm than good in the long run.
This satisfies 1..
This is quite a high priority feature for Yew and I would love to help out with this.
Tide is supposed to have "mime type guessing", which should be able to handle a .js
extension I'd think.
https://github.com/http-rs/tide/pull/461/files
mime_guess
crates has a application/javascript
https://github.com/abonander/mime_guess/blob/master/src/mime_types.rs
When working on web-view based desktop application, you don't have access automatically to a server to serve your application front-end files, and it's a lot simpler just to pass in the entire front-end inlined as a single HTML file. It would be nice if Trunk had support for this.
I have a link to sass file in my index.html like that
<link rel="stylesheet" href="scss/index.scss">
On Unix platforms this works when running trunk serve
from the crate directory.
However, on Windows I get an error:
skipping invalid path: \\?\C:\Users\USERNAME\PATH_TO_WD\frontend\scss/index.scss
It seems that trunk does not properly map the slash to the backslash as a forward slash can be seen in the error message.
It works fine if i replace the slash with a backslash, but that would break unix platforms.
The trunk serve
command needs the ability to proxy some URLs to a configured backend, particularly for cases where the UI makes requests to backend data APIs on the same host which served the UI application, nested under a different URI prefix. This is a very common deployment pattern.
trunk serve --proxy-backend
flag. This flag will take a valid URL, where the protocol, host, and port segments will be used as the proxy backend target, and the URI portion will be treated as the URI to proxy. E.G., for http://localhost:3000/api/
Trunk will proxy any requests received at /api/
over to the target backend, same URI, headers &c.--proxy-backend
option is specified, the serve
subcommand should add a handler for the backend's URI. The handler should transparently proxy any received requests over to the configured backend, returning the response from the backend to the client.trunk serve --proxy-rewrite
flag. This flag will take a valid URI, and will use it as the URI which is to be proxied, stripping the given prefix and rewriting it to match the URI of --proxy-backend
.Trunk.toml
called [proxy]
. It will only be supported in the config file. No env vars or CLI opts.backend
to be specified. This describes the backend target. The URI provided for the backend will be used as the proxy URI by default.rewrite
can be provided which will make the proxy handle the given URI as the entrypoint, but will then re-write the URI segment to match the backend
's URI. E.G., rewrite=/dev/v1/
backend=http://localhost:3000/api/
will cause Trunk to proxy requests received on /dev/v1/
over the the backend at http://localhost:3000/api/
, and the /dev/v1/
portion of the URI of the original request will be stripped and rewritten as simply /api/
matching the backend.--proxy-backend
is specified on the CLI, then Trunk.toml
proxies will be ignored (following the config layers pattern).#29
#31 (though this one will require separate treatment and functionality)
Due to grass not supporting sass indented syntax at this time, I will be looking into cutting this over to sass-rs for now.
Right now, it expects the target to be a file. If it is a dir, we should recursively copy it.
wasm-bindgen has the ability to automatically include javascript files referenced in the code:
use wasm_bindgen::prelude::*;
#[wasm_bindgen(module = "/get-payload-script.js")]
extern "C" {
#[wasm_bindgen(js_name = "getPayload")]
pub fn get_payload() -> String;
}
It does this by including these referenced files in a directory called "snippets" which is located in the output directory.
They are then imported in the index.js
file:
import { getPayload } from './snippets/js_callback/get-payload-script.js';
Trunk doesn't seem to handle this right now so these snippets aren't included in the output.
Right now it is valid and correct ... just not formatted very well.
There may be some other corner cases here. Review the Cargo docs, and make sure we process the crate names the same way that Cargo does. Unless anyone else has a better option.
Also, thanks @MartinKavik for the report.
Currently, Trunk will continue to accumulate artifacts in the dist
dir as changes continue to take place. This can be a bit overwhelming, and is something we should clean-up.
One approach may be to build a manifest of paths generated per build. At the very end of the build, we will go through the dist
dir and remove anything which was not generated as part of the current build.
dist
, let's call it .current
, which represents the artifacts being accumulated in the current build.dist/.current
will be deleted before any new build is started.dist
dir (except for the .current
dir), and then immediately move all of the contents of dist/.current
up into dist
.This will ensure that we do not continuously accumulate artifacts as builds take place, and will also ensure that artifacts are not prematurely deleted in case of application compilation errors on the user's behalf.
Currently, if an asset has an incorrect path, Trunk will just skip that resource. It would probably be good to at least log a warning if the asset appears as though it is referencing a resource on the filesystem but which has an invalid path.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.