koute / cargo-web

A Cargo subcommand for the client-side Web
Apache License 2.0
1.11k stars 80 forks source link

Allow cargo web deploy output to a custom folder #96

Open limira opened 6 years ago

limira commented 6 years ago

If I understand correctly, cargo-web deploy currently only:

By saying web-url root I mean the server app must serve the .wasm file at www.example.com/filename.wasm for the app to work properly.

What I want is to be able to serve .wasm file from a custom url such as www.example.com/javascript/filename.wasm. Also, I want cargo web deploy output files to a custom path such as ../../my-web-app/javascript that is relative to the location of Web.toml

To implement this, I think we must add an entry to Web.toml like this:

[deploy]
# not include domain name (www.example.com)
js-url = "/url/to/serve/javascript" 

# .js and .wasm will be copy to this (It is relative to Web.toml)
js-path = "../..my-web-app/javascript" 

# /static/*.* will be copy to this (if src/static/ exists)
static-path = "../../my-web-app/static" 

If this is acceptable. I will implement it. (I am very new to Rust and cargo-web, I hope you give me some instructions, for example: which file.rs(s) will be involved)

koute commented 6 years ago

A few general points regarding this:

  1. I don't think we need the static-path; e.g. if you want it to emit files so that they're available under https://example.com/static/ then you can just put them in src/static/static (as everything in src/static will get copied).

  2. As far as how this would look in Web.toml, something like this perhaps:

# This is the default; it specifies to which directory the files are copied when running `cargo deploy`; relative to where `Cargo.toml` is.
deploy-path = "target/deploy"

# This is under which URL the generated artifacts are served (*both* the `.js` file and the `.wasm` file). Relative to the `deploy-path` on the local filesystem, and relative to the hostname when serving through HTTP.
serve-path = "/"

[target.wasm32-unknown-unknown]
# These can also be overriden per each target.
deploy-path = "another/path"
serve-path = "yet/another/path
  1. In a nutshell - the main place where these would have to be added are in config.rs. The cmd_deploy.rs would have to be modified to deploy to correct directory, in deployment.rs we'd have to take into the account the path from which the .js and the .wasm are served, and the .js runtime generation would also have to be modified.
limira commented 6 years ago

With current wanted design of deploy-path and serve-path, it is not applicable for my particular case.

My project have static files that organize like this:

/ static
    /files-from-other-source/*.*          (hundreds of them, rarely change)
    /wasm-static/*.*     (other files related to .wasm project)
    /name.js
    /name.wasm
    /index.html

I want all of them to be in one directory to be easily served by one instance of StaticFile server. But if I have:

Web.toml
deploy-path = path/to/my/static
serve-path = /

Then, cargo web deploy will remove current contents of /static before copying new output to it. Then, /files-from-other-source/ must be recopied (I don't want this).

If putting all wasm related things into it own folder:

/ static
    /other-files/*
    /wasm-files
        /wasm-static/*
        /name.js
        /name.wasm
        /index.html

Web.toml

deploy-path = path/to/wasm-files
serve-path = /

Then, the .js will load .wasm file at /, but it is actually serve at /wasm-files.

So, I want to add a third parameter like this: Web.toml

# `deploy-path` is where to deploy current project.
# Content of `static/*.*` will be copied here.
# `.js` and `.wasm` files will be in this path or sub-path depend
# on value of `js-wasm-deploy-path` (see next).
deploy-path = path/to/deploy

# `js-wasm-deploy-path` (sub and relative to `deploy-path`) is where to
# output `.js` and `.wasm` files.
# Default is '/' (means the same as `deploy-path`)
#
# This apply to all command `cargo web build/deploy/start`
js-wasm-deploy-path = /

# [Optional]
# `serve-path` is the `url` that `.js` and `.wasm` are served by the server
# If omitted, its value will be the same as `js-wasm-deploy-path`
#
# This apply to all command `cargo web build/deploy/start`
serve-path = /wasm-files

What do you think about this?

koute commented 6 years ago

Right, yes, it will clear the directory out - good point. In that case we could just add a parameter with which you could disable that (or actually - enable it; ideally we should have it clear the directory by default only when using default deploy path.)

thedodd commented 6 years ago

On this particular front, I think there is a lot to be gathered from the ParcelJS & Webpack projects — as well as other bundling tools. First, a few reflections:

Given the above reflections, I think that being able to output the wasm artifact to a specific directory is paramount for interop with Webpack, ParcelJS & other bundlers.

I definitely see an ideal setup for production grade web apps using this tool. Let's say we have an all wasm project, which is using SASS for styles: For development:

For deployment: the pipeline would look something like this:

I do everything in Docker, so I would just have all of this execute in a docker container, and then deploy the docker container with all of the built artifacts.

Thoughts?

limira commented 6 years ago

These are just my personal experiences. I want to make clear that I am not an experienced developer (but a crazy one :grin: ). I have never built a real web app before. Currently I am building my first ever web app. I hope it will go into production in someday. [And sorry for my poor English]

I actually started my current project in JS (using ReactJS, Webpack) and Go. After roughly a year, I replaced Go by Rust. About 2 months ago, I want to have a big change in JS part of my application. I was hesitate..., after nearly 2 years working with JS, I think JS is not a good language to make (even a single) big change into its app source code. I counted my JS code: 40k lines, I don't know it is big for you or not. But for me, it not good to introduce a big change into that much code in a language like JS. Another bad thing: my code is is a mess (I am not an experienced developer). I also want to rewrite it! In JS again? NO..... NEVER JS AGAIN!

Again, I am not an experienced developer. I need helps to write better code, Rust - as a language itself - give helps that I need. I look around, wow, there is thing like yew to replace ReactJS. It is not mature yet, but is growing. And I am happy to contribute to make it work for me, some contributions reach out to stdweb, cargo-web... Now I am in the process of rewrite my entirely app of about 100k lines of code in both back-end and front-end, everything (almost) in Rust. There will be zero .js file that written by myself in my project any more. (Everything is just because I am a crazy developer).

I think I understand why you say that long comment above. It come from good will to make other people aware the situation and not to reinvent the wheel (am I correct?). But there are still many people that crazy enough to try to reinvent it. Not all crazy people have the ability to change the world (I am among them). But the world changes because of some great crazy people, and I am happy to support them.

LaylBongers commented 6 years ago

I'm running into a similar issue where I just want to serve my JS and WASM from a static/ route, but since the WASM path is hardcoded in the JS I can't do that.

paulirotta commented 4 years ago

I have a similar requirement, to be able to deploy an example similar to ´cargo run --example foo´

I mention it here rather than an own issue as it might be part of this line of development (and to keep the issue count reasonable).