rustwasm / wasm-pack Goto Github PK
View Code? Open in Web Editor NEW๐ฆโจ your favorite rust -> wasm workflow tool!
Home Page: https://rustwasm.github.io/wasm-pack/
License: Apache License 2.0
๐ฆโจ your favorite rust -> wasm workflow tool!
Home Page: https://rustwasm.github.io/wasm-pack/
License: Apache License 2.0
This is related to https://github.com/rust-lang-nursery/rust-wasm/issues/34 and https://github.com/rust-lang-nursery/rust-wasm/issues/36, but I'd like to propose a strawman idea here.
Right now wasm-bindgen has the ability to say where you're importing functionality from:
#[wasm_bindgen(module = "foo")]
extern {
// ...
}
If module = "..."
is omitted it's assumed to come from the ambient environment (aka the browser). Otherwise foo
is interpreted as an ES module directive and that's where items are imported from in the generated JS that wasm-bindgen emits.
The wasm-bindgen output is pretty "dumb" right now in that it's just bland ES module information, it doesn't currently attempt to give extra information like verison requirements for NPM packages. But that's where wasm-pack comes in! Ideally wasm-bindgen would emit information that wasm-pack later reads, parses, and emits a package.json for.
So I'd propose something like:
version = "..."
next to module = "..."
in wasm-bindgenmodule = "..."
directives that don't start with .
, require that version
is listedwasm-bindgen
emits in the format:
__wasm_pack_unstable
{ "module": "string", "version": "string" }
wasm-pack
executes it slurps up the __wasm_pack_unstable
section, if present, and emits these packages into the package.json
that's generated.An example of using this would look like:
#[wasm_bindgen(module = "moment", version = "2.0.0")]
extern {
type Moment;
fn moment() -> Moment;
#[wasm_bindgen(method)]
fn format(this: &Moment) -> String;
}
#[wasm_bindgen]
pub fn run() -> String {
moment().format()
}
And wasm-pack
would automatically generate a package.json
with:
{
"dependencies": {
"moment": "2.0.0"
}
}
I'm definitely up for changing anything here, this is just an initial strawman! I'd love to hear others' thoughts on this as well.
When using wasm-pack init
the following output is produced:
โ
rustup_add_wasm_target succeeded and stdout was:
โ
cargo_build_wasm succeeded and stdout was:
๐๏ธ ๐จ compiled to wasm!
This makes it seem like there was supposed to be output. If there's not it should just cut off the rest of the sentance after and.
"I want to use quicli to quickly build CLI apps โ And I want to stop there! If you are no longer writing a small CLI tool (Iโd say something like 500 lines of code is no longer small), your problems are likely more complicated than what quicli gives you tools for." from quicli - The ideas behind my small Rust CLI framework
We're over 500 and I think it gave us a good starting point to get this built up but as we expand features and logging we will need to be more selective of imports and we don't need everything from the prelude, which there was a not used
warning I could not get rid of unless I imported some crates anyways. I think we should take what crates we need from quicli then fix up the code to work without it.
I have this on a wip bit of code whereby in command.rs
I removed the prelude
import to get rid of the warning during compilation. I had to import structopt derive into the crate as well for that to work.
Thoughts @ashleygwilliams?
we have pack and publish wrapped up, we might as well wrap login as well
after talking with @alexcrichton about this, it seems like shelling out vs using cargo/wasm-bindgen as libraries is not a clear call. shelling out is easier so i'mma do that for now! we may move to the library usage later tho.
Hello! I was following the tutorial for wasm-pack and got to this step: https://rust-lang-nursery.github.io/rust-wasm/wasm-pack/package-code.html
Compiling took a while and then printed this:
wasm-pack -v init --scope thallada
[1/7] Adding WASM target...
[2/7] Compiling to WASM...
[3/7] Creating a pkg directory...
[4/7] Writing a package.json...
| [5/7] Copying over your README...
| :-) [WARN]: origin crate has no README
[6/7] Installing WASM-bindgen...
[7/7] Running WASM-bindgen...
:-) Done in 1 minute
:-) Your WASM pkg is ready to publish at ./pkg
But, if I look at the ./pkg
directory, there's only a package.json
file:
$ ls pkg/
package.json
Do you know what might have gone wrong?
$ npm --version
v9.11.1
$ npm --version
5.6.0
$ rustup show
Default host: x86_64-unknown-linux-gnu
installed toolchains
--------------------
stable-x86_64-unknown-linux-gnu
nightly-x86_64-unknown-linux-gnu (default)
installed targets for active toolchain
--------------------------------------
asmjs-unknown-emscripten
wasm32-unknown-emscripten
wasm32-unknown-unknown
x86_64-unknown-linux-gnu
active toolchain
----------------
nightly-x86_64-unknown-linux-gnu (default)
rustc 1.27.0-nightly (ac3c2288f 2018-04-18)
When using wasm-pack via wasm-pack init
only one field at a time is output as to what's missing from the Cargo.toml file. It would be nicer if all the fields missing were printed out all at once!
Due to the way examples is used, they're not recognized by Cargo, and therefore, not compiled when cargo test
is run.
@mgattozzi brought this up while working on the tutorial. we should support namespaces (which are called scopes in npm land)! this way people taking the tutorial won't all attempt to publish a pkg with the same name.
wasm-pack init --scope MYSCOPE
should write to the package.json:
{
"name": "@MYSCOPE/cratename"
}
When I read "wasm-pack" I think of something that packages .wasm
code into a .zip
or .tar.gz
file. It also might cause some confusion with the npm pack
command.
Instead, I think "wasm2npm" or "wasm-to-npm" would be much better names. They make it clear that this tool is designed to be used with npm, and they also make it clearer what it does (it converts .wasm
into a form that npm can understand).
as of #19 we can take a path as an argument
current behavior: creates pkg
dir in current path
question: should it create the pkg
dir in current path or the one provided?
it needs a change log, once #97 lands i'll write one up
When first running wasm-pack there's no indication that wasm-bindgen is being installed at first. I had a huge spike in CPU usage and was confused why it happened the first time I ran the command. It wasn't until looking in the code for something that I saw why.
If this is the first time then we should print out that it will be compiled and installed. If it's not and it exists and the version is not outdated we should print out that it's already installed. If it's installed and outdated we should print out that we're updating it.
it looks gross right now
This issue is reserved for someone who has not yet contributed to this codebase.
Currently we read the Cargo.toml twice! this is not preferred:
MENTORING INSTRUCTIONS (from @mgattozzi !):
Cargo.toml
file to a String
and assign it to a variable, maybe something like CARGO_TOML
we can grab author data from Cargo as well, but we MIGHT consider checking if there is an .npmrc
and preferring that if it exists
#49 turned off all the stdout/err fwding. this output is still useful for debugging when people run into issues, so let's write it to a wasm-pack-debug.log
so- i originally put rustfmt in CI because i like enforcing style. however because this is on nightly and not yet stabilized the contributor experience is p poopy (cc @yoshuawuyts). thoughts on me ripping it out and just running it and commiting everyone once in a while? (this can make history really gross and i do love using git as a good history tool, but it might not be worth it at this point)
some of the build steps, particularly the compilation step is a little long, it might be nice to have some progress bars? is there an efficient rust progress bar lib for the CLI? @killercup maybe you know?
after #40 we didn't update the readme. oops!
right now i'm lazily(read: barely) using Failure and haven't defined any error shenanigans. i should fix that!
as per @mgattozzi's comments on #67 and my own nagging gut, let's refactor out those panics when we are shelling out so we can have nicer error handling
there are several steps to using wasm-bindgen
that i'd like to discuss here:
rustup target add wasm32-unknown-unknown
add wasm-bindgen
as a dep to Cargo.toml
:
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = { git = 'https://github.com/alexcrichton/wasm-bindgen' }
add the following code to your src/lib.rs
:
#![feature(proc_macro)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
add this annotation to each publicly exported function:
#[wasm_bindgen]
#[no_mangle]
cargo build --release --target wasm32-unknown-unknown
cargo install --git https://github.com/alexcrichton/wasm-bindgen
(this seems redundant with 2??? https://github.com/alexcrichton/wasm-bindgen/issues/44)
wasm-bindgen target/wasm32-unknown-unknown/release/<name of lib>.wasm \ --out-dir .
(ergonomics ask: https://github.com/alexcrichton/wasm-bindgen/issues/45)
i can see clear ways to integrate 1, 2, 5, 6, 7. 3 and 4 will need to be done manually by the user. @alexcrichton do you have any thoughts on this?
for 0.1.0 let's just copy over the README.md from the crate
there's great convo in #7 and i'd like to move to something more like that for 0.2.0 or greater.
currently i'm "testing" this tool by running it recrusively on itself (i.e. using the wasm-pack cargo.toml and wasm-pack rust files to compile)
this stops working now that i'm trying to build to wasm, as much of the code in the rust files for this project won't compile to wasm for several reasons.
rewrite this to be targeting an example so it actually compiles
https://crates.io/crates/indicatif (thanks for the suggestion @killercup)
take a --typescript
flag to wasm-bindgen
and add a types
key to the package.json
http://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html
This is extremely awesome - https://github.com/parcel-bundler/parcel
It's in js/npm ecosystem, so if wasm-pack takes it as an aim to be like rusty parcel I will be extremely happy, so my question - is it realistic that wasm-pack takes parcel as a guiding bar level?
In the wasm-add example, the main JS file in the generated module is wasm-add/wasm_add.js
. This means that you have to specify the JS filename when importing that module e.g. through webpack.
If the generated JS file were called index.js
instead, or if its name was declared as the main file using the main
property in the module's package.json, one would be able to use just import("wasm-add")
to import the module, which would be a bit nicer.
This would also allow the "test in your browser" button on the npm package site to work more smoothly. For example, if you click that button on https://www.npmjs.com/package/@mgattozzi/wasm-add, you get to https://npm.runkit.com/@mgattozzi/wasm-add, which says:
@mgattozzi/wasm-add
lists no main file and has no index.js, so it can't be directly required. If this is a mistake, please let us know. It may however contain internal files that you can require manually
Trying to install with:
cargo install wasm-pack
Results in:
Updating registry `https://github.com/rust-lang/crates.io-index`
Installing wasm-pack v0.1.0
Compiling vec_map v0.8.0
Compiling cfg-if v0.1.2
Compiling stable_deref_trait v1.0.0
Compiling lazy_static v1.0.0
Compiling unicode-width v0.1.4
Compiling memoffset v0.2.1
Compiling serde v1.0.38
Compiling glob v0.2.11
Compiling itoa v0.4.1
Compiling unicode-xid v0.0.4
Compiling void v1.0.2
Compiling dtoa v0.4.2
Compiling ansi_term v0.11.0
Compiling unicode-xid v0.1.0
Compiling quote v0.3.15
Compiling termcolor v0.3.6
Compiling lazy_static v0.2.11
Compiling rayon-core v1.4.0
error: linker `cc` not found
|
= note: No such file or directory (os error 2)
error: aborting due to previous error
error: Could not compile `rayon-core`.
warning: build failed, waiting for other jobs to finish...
error: failed to compile `wasm-pack v0.1.0`, intermediate artifacts can be found at `/var/folders/lt/21g7hfd10_7_b95nnh8_ymb40000gn/T/cargo-install.HSJZjCqOt4RL`
Caused by:
build failed
when running wasm-pack
when there is currently not a description prevents building. Would be nice if description was optional or documented as required:
ฮป wasm-pack init
[1/7] ๐ฏ Adding WASM target...
[2/7] ๐ Compiling to WASM...
[3/7] ๐ Creating a pkg directory...
missing field `description` for key `package`
we support commonjs in wasm-bindgen now, let's have it be an option to pass to wasm pack!
Otherwise at the whims of whatever is on wasm-bindgen master, which bit us today.
Currently we install wasm-bindgen
as a git dep. but we shouldn't! it's published on Cargo now! change these lines to run cargo install wasm-bindgen
and not pass the git
flag as we do right now. Feel free to ping me (@ag_dubs) on https://kiwiirc.com/client/irc.mozilla.org:+6667/#rust-wasm for help or any questions!
currently if the crate doesn't have a readme it just kinda skips over. i think it'd be nice to warn
right now the cli assume you are running the tool in the directory you want packed. this makes testing this thing a huge pain in the butt. let's optionally take a argument that points to the path of a Cargo.toml
(cargo does this as well)
blocking #19
https://github.com/japaric/trust/ or https://github.com/alexcrichton/stamp-rs should help us with this
in generating an npm package from a rust/wasm project do we anticipate that the author would want to reuse the README from the rust crate or create a new one?
While my tutorial over on rust-wasm hasn't landed in the book yet it will soonish. However, we want people to be able to reference something a little less longform as well because sometimes all you need is a few words describing how to use the tool.
We should make docs that are short like the readme but explain things like using the scope flag etc. Also maybe even use asciinema to show some visual examples for people!
wasm-bindgen was released! we should use the cargo version instead of a git dep :)
happy to have a contributor pick this one up
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.