Merge branch 'master' into feature-wasm-bindgen-detection

master
ashley williams 7 years ago committed by GitHub
commit f449346416
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 83
      README.md
  2. 44
      docs/contributing.md
  3. 11
      docs/init.md
  4. 8
      src/bindgen.rs
  5. 18
      src/build.rs
  6. 30
      src/command.rs
  7. 24
      src/manifest.rs
  8. 3
      tests/fixtures/bad-cargo-toml/Cargo.toml
  9. 15
      tests/manifest/main.rs

@ -1,56 +1,39 @@
# 📦✨ wasm-pack
> pack up the wasm and publish it to npm!
> Your favorite rust -> wasm workflow tool!
[![Build Status](https://travis-ci.org/ashleygwilliams/wasm-pack.svg?branch=master)](https://travis-ci.org/ashleygwilliams/wasm-pack)
[![Build status](https://ci.appveyor.com/api/projects/status/7jjuo5wewu9lyyfi?svg=true)](https://ci.appveyor.com/project/ashleygwilliams/wasm-pack)
the goal of this project is to create a portable command line tool
for publishing compiled wasm projects to the npm registry for the consumption
of js devs using the npm CLI, yarn, or any other CLI tool that interfaces
with the npm registry.
This tool seeks to be a one-stop shop for building and working with rust-
generated WebAssembly that you would like to interop with JavaScript, in the
browser or with Node.js. `wasm-pack` helps you build and publish rust-generated
WebAssembly to the npm registry to be used alongside any other javascript
package in workflows that you already use, such as a bundler like
[webpack] or [greenkeeper].
this project is a part of the [rust-wasm] group. you can find more info by
[bundler-support]: https://github.com/rustwasm/team/blob/master/goals/bundler-integration.md#details
[webpack]: https://webpack.js.org/
[greenkeeper]: https://greenkeeper.io/
This project is a part of the [rust-wasm] group. You can find more info by
visiting that repo!
[rust-wasm]: https://github.com/rust-lang-nursery/rust-wasm/
![demo](demo.gif)
## 🔮 prerequisities
this project is written in rust. [get rust] to work on this project.
[get rust]: https://www.rustup.rs/
if you want to publish packages, you'll also need an account on [npm] and have
[node/npm] installed.
## 🔮 Prerequisities
[npm]: https://www.npmjs.com
[node/npm]: https://nodejs.org/
- [Development Environment](docs/prerequisites.md)
- [Installation and Getting Started](docs/setup.md)
## 🏃 up and running
## 🎙 Commands
1. fork and clone this repository
2. install [node/npm]
2. `cd wasm-pack`
3. `cargo run`
- [`init`](docs/init.md): Generate an npm wasm pkg from a rustwasm crate
- [`pack`](docs/pack.md): Create a tarball of your rustwasm pkg
- [`publish`](docs/publish.md): Publish your rustwasm pkg to a registry
## 💃 commands
- `help`: display available commands
- 🐣 `init`: create necessary files for js interop and npm publishing
- optionally pass a path to a dir that contains a `Cargo.toml`, e.g.:
```
wasm-pack init examples/js-hello-world
```
- optionally pass a scope name to generate a `package.json` for a scoped pkg, e.g.:
```
wasm-pack init examples/scopes-hello-world --scope test
```
generates a `package.json` for an npm package called `@test/scopes-hello-world`
- 🍱 `pack`: create a tarball but don't push to the npm registry (see https://docs.npmjs.com/cli/pack)
- 🎆 `publish`: create a tarball and publish to the npm registry (see https://docs.npmjs.com/cli/publish)
### logging
## 📝 Logging
We generate a `wasm-pack.log` file if `wasm-pack` errors on you, and you can
customize the log verbosity using the verbosity flag.
@ -61,11 +44,18 @@ customize the log verbosity using the verbosity flag.
| -vv | All Debug, Info, Warn, and Errors are logged |
| -vvv | All Trace, Debug, Info, Warn, and Errors are logged |
## 👯 Contributing
Read our [guide] on getting up and running for developing `wasm-pack`, and
check out our [contribution policy].
[guide]: doc/contributing.md
[contribution policy]: CONTRIBUTING.md
## ⚙ how to use
## ⚡ Quickstart Guide
1. write a crate in Rust.
2. add `wasm-bindgen` to your `Cargo.toml`:
1. Write a crate in Rust.
2. Add `wasm-bindgen` to your `Cargo.toml`:
```toml
[lib]
@ -74,7 +64,7 @@ customize the log verbosity using the verbosity flag.
[dependencies]
wasm-bindgen = "0.2"
```
3. add this to the top of your `src/lib.rs`:
3. Add this to the top of your `src/lib.rs`:
```rust
#![feature(proc_macro, wasm_import_module, wasm_custom_section)]
@ -84,7 +74,7 @@ customize the log verbosity using the verbosity flag.
use wasm_bindgen::prelude::*;
```
4. annotate your public functions with `#[wasm_bindgen]`, for example:
4. Annotate your public functions with `#[wasm_bindgen]`, for example:
```rust
#[wasm_bindgen]
@ -98,10 +88,11 @@ customize the log verbosity using the verbosity flag.
}
```
5. install this tool: `cargo install wasm-pack`
6. run `wasm-pack init`, optionally, pass a path to a dir or a scope (see above for details)
7. this tool generates files in a `pkg` dir
8. to publish to npm, run `wasm-pack publish` (making sure you are logged in with npm)
5. Install this tool: `cargo install wasm-pack`
6. Run `wasm-pack init`, optionally, pass a path to a dir or a scope (see above for details)
7. This tool generates files in a `pkg` dir
8. To publish to npm, run `wasm-pack publish`. You may need to login to the
registry you want to publish to. You can login using `wasm-pack login`.`
[rust-wasm/36]: https://github.com/rust-lang-nursery/rust-wasm/issues/36
[wasm-bindgen]: https://github.com/alexcrichton/wasm-bindgen

@ -0,0 +1,44 @@
# Contributing
## Prerequisites
The technical prerequisites for contributing to this project are the same as for
using it. You can find them documented [here][1].
You'll also want to check out the contributing [guidelines].
[1]: docs/prerequisites.md
[guidelines]: CONTRIBUTING.md
## 🏃 Up and Running
1. fork and clone this repository
2. install [node/npm]
2. `cd wasm-pack`
3. `cargo run`. To test command line arguments you can run `cargo run -- <args>`.
## Documentation
Documentation lives in the [`/docs`](docs) directory. Each command has it's own page.
Additionally there are extra pages explaining the prerequisites, setup, and how to
contribute (which you are reading now!).
## Tests
Tests live in the [`/tests`](tests) directory. To run the tests you can run:
```
cargo test
```
You can also manually test the CLI tool by running:
```
cargo run -- <args>
```
...for example:
```
cargo run -- init /tests/fixtures/js-hello-world --scope=ag_dubs
```

@ -46,4 +46,15 @@ This command would create a `package.json` file for a package called
`@test/js-hello-world`. For more information about scoping, you can refer to
the npm documentation [here][npm-scope-documentation].
## Debug
The init command accepts an optional `--debug` argument. This will build the
output package using cargo's
[default non-release profile][cargo-profile-sections-documentation]. Building
this way is faster but applies few optimizations to the output, and enables
debug assertions and other runtime correctness checks.
The exact meaning of this flag may evolve as the platform matures.
[npm-scope-documentation]: https://docs.npmjs.com/misc/scope
[cargo-profile-sections-documentation]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections

@ -34,6 +34,7 @@ pub fn wasm_bindgen_build(
name: &str,
disable_dts: bool,
target: String,
debug: bool,
) -> Result<(), Error> {
let step = format!(
"{} {}Running WASM-bindgen...",
@ -42,8 +43,11 @@ pub fn wasm_bindgen_build(
);
let pb = PBAR.message(&step);
let binary_name = name.replace("-", "_");
let wasm_path = format!("target/wasm32-unknown-unknown/release/{}.wasm", binary_name);
let release_or_debug = if debug { "debug" } else { "release" };
let wasm_path = format!(
"target/wasm32-unknown-unknown/{}/{}.wasm",
release_or_debug, binary_name
);
let dts_arg = if disable_dts == false {
"--typescript"
} else {

@ -25,20 +25,22 @@ pub fn rustup_add_wasm_target() -> Result<(), Error> {
}
}
pub fn cargo_build_wasm(path: &str) -> Result<(), Error> {
pub fn cargo_build_wasm(path: &str, debug: bool) -> Result<(), Error> {
let step = format!(
"{} {}Compiling to WASM...",
style("[2/7]").bold().dim(),
emoji::CYCLONE
);
let pb = PBAR.message(&step);
let output = Command::new("cargo")
.current_dir(path)
.arg("build")
.arg("--release")
.arg("--target")
.arg("wasm32-unknown-unknown")
.output()?;
let output = {
let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("build");
if !debug {
cmd.arg("--release");
}
cmd.arg("--target").arg("wasm32-unknown-unknown");
cmd.output()?
};
pb.finish();
if !output.status.success() {
let s = String::from_utf8_lossy(&output.stderr);

@ -32,6 +32,10 @@ pub enum Command {
#[structopt(long = "target", short = "t", default_value = "browser")]
/// Sets the target environment. [possible values: browser, nodejs]
target: String,
#[structopt(long = "debug")]
/// Build without --release.
debug: bool,
},
#[structopt(name = "pack")]
@ -84,17 +88,19 @@ pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error
scope,
disable_dts,
target,
debug,
} => {
info!(&log, "Running init command...");
info!(
&log,
"Path: {:?}, Scope: {:?}, Disable Dts: {}, Target: {}",
"Path: {:?}, Scope: {:?}, Disable Dts: {}, Target: {}, Debug: {}",
&path,
&scope,
&disable_dts,
&target
&target,
debug
);
init(path, scope, disable_dts, target, &log)
init(path, scope, disable_dts, target, &log, debug)
}
Command::Pack { path } => {
info!(&log, "Running pack command...");
@ -164,6 +170,7 @@ fn init(
disable_dts: bool,
target: String,
log: &Logger,
debug: bool,
) -> result::Result<(), Error> {
let started = Instant::now();
@ -178,7 +185,7 @@ fn init(
info!(&log, "Adding wasm-target was successful.");
info!(&log, "Building wasm...");
build::cargo_build_wasm(&crate_path)?;
build::cargo_build_wasm(&crate_path, debug)?;
#[cfg(not(target_os = "windows"))]
info!(
@ -215,6 +222,19 @@ fn init(
#[cfg(target_os = "windows")]
info!(&log, "Copied readme from crate to {}\\pkg.", &crate_path);
info!(&log, "Checking the crate type from the manifest...");
manifest::check_crate_type(&crate_path)?;
#[cfg(not(target_os = "windows"))]
info!(
&log,
"Checked crate type from the manifest at {}/Cargo.toml.", &crate_path
);
#[cfg(target_os = "windows")]
info!(
&log,
"Checked crate type from the manifest at {}\\Cargo.toml.", &crate_path
);
info!(&log, "Installing wasm-bindgen-cli...");
bindgen::cargo_install_wasm_bindgen()?;
info!(&log, "Installing wasm-bindgen-cli was successful.");
@ -233,7 +253,7 @@ fn init(
);
info!(&log, "Building the wasm bindings...");
bindgen::wasm_bindgen_build(&crate_path, &name, disable_dts, target)?;
bindgen::wasm_bindgen_build(&crate_path, &name, disable_dts, target, debug)?;
#[cfg(not(target_os = "windows"))]
info!(&log, "wasm bindings were built at {}/pkg.", &crate_path);
#[cfg(target_os = "windows")]

@ -12,6 +12,7 @@ use PBAR;
struct CargoManifest {
package: CargoPackage,
dependencies: Option<CargoDependencies>,
lib: Option<CargoLib>,
}
#[derive(Deserialize)]
@ -30,6 +31,12 @@ struct CargoDependencies {
wasm_bindgen: Option<String>,
}
#[derive(Deserialize)]
struct CargoLib {
#[serde(rename = "crate-type")]
crate_type: Option<Vec<String>>,
}
#[derive(Serialize)]
struct NpmPackage {
name: String,
@ -155,3 +162,20 @@ pub fn check_wasm_bindgen(path: &str) -> Result<(), Error> {
style("wasm-bindgen").bold().dim()
))
}
fn has_cdylib(path: &str) -> Result<bool, Error> {
Ok(read_cargo_toml(path)?.lib.map_or(false, |lib| {
lib.crate_type
.map_or(false, |types| types.iter().any(|s| s == "cdylib"))
}))
}
pub fn check_crate_type(path: &str) -> Result<(), Error> {
if !has_cdylib(path)? {
Error::crate_config(
"crate-type must include cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:\n\n[lib]\ncrate-type = [\"cdylib\"]"
)
} else {
Ok(())
}
}

@ -3,4 +3,7 @@ name = "bad-cargo-toml"
version = "0.1.0"
authors = ["Michael Gattozzi <mgattozzi@gmail.com>"]
[lib]
crate-type = ["foo"]
[dependencies]

@ -25,6 +25,21 @@ fn it_gets_the_crate_name_provided_path() {
);
}
#[test]
fn it_checks_has_cdylib_default_path() {
assert!(manifest::check_crate_type(".").is_err());
}
#[test]
fn it_checks_has_cdylib_provided_path() {
assert!(manifest::check_crate_type("tests/fixtures/js-hello-world").is_ok());
}
#[test]
fn it_checks_has_cdylib_wrong_crate_type() {
assert!(manifest::check_crate_type("tests/fixtures/bad-cargo-toml").is_err());
}
#[test]
fn it_creates_a_package_json_default_path() {
let path = ".".to_string();

Loading…
Cancel
Save