mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-22 01:01:34 +00:00
Merge pull request #1305 from alexcrichton/npm-dependencies
Implement transitive support for NPM dependencies
This commit is contained in:
@ -66,7 +66,7 @@ members = [
|
|||||||
"examples/fetch",
|
"examples/fetch",
|
||||||
"examples/guide-supported-types-examples",
|
"examples/guide-supported-types-examples",
|
||||||
"examples/hello_world",
|
"examples/hello_world",
|
||||||
"examples/import_js",
|
"examples/import_js/crate",
|
||||||
"examples/julia_set",
|
"examples/julia_set",
|
||||||
"examples/paint",
|
"examples/paint",
|
||||||
"examples/performance",
|
"examples/performance",
|
||||||
|
@ -62,12 +62,17 @@ jobs:
|
|||||||
- template: ci/azure-install-sccache.yml
|
- template: ci/azure-install-sccache.yml
|
||||||
- script: cargo test --target wasm32-unknown-unknown --features nightly --test wasm
|
- script: cargo test --target wasm32-unknown-unknown --features nightly --test wasm
|
||||||
|
|
||||||
- job: test_cli_support
|
- job: test_cli
|
||||||
displayName: "Run wasm-bindgen-cli-support crate tests"
|
displayName: "Run wasm-bindgen-cli crate tests"
|
||||||
steps:
|
steps:
|
||||||
- template: ci/azure-install-rust.yml
|
- template: ci/azure-install-rust.yml
|
||||||
- template: ci/azure-install-sccache.yml
|
- template: ci/azure-install-sccache.yml
|
||||||
|
- script: rustup target add wasm32-unknown-unknown
|
||||||
|
displayName: "install wasm target"
|
||||||
- script: cargo test -p wasm-bindgen-cli-support
|
- script: cargo test -p wasm-bindgen-cli-support
|
||||||
|
displayName: "wasm-bindgen-cli-support tests"
|
||||||
|
- script: cargo test -p wasm-bindgen-cli
|
||||||
|
displayName: "wasm-bindgen-cli tests"
|
||||||
|
|
||||||
- job: test_web_sys
|
- job: test_web_sys
|
||||||
displayName: "Run web-sys crate tests"
|
displayName: "Run web-sys crate tests"
|
||||||
@ -139,16 +144,22 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- template: ci/azure-install-rust.yml
|
- template: ci/azure-install-rust.yml
|
||||||
- template: ci/azure-install-sccache.yml
|
- template: ci/azure-install-sccache.yml
|
||||||
- script: npm install
|
- script: mv _package.json package.json && npm install && rm package.json
|
||||||
|
displayName: "run npm install"
|
||||||
- script: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
|
- script: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
|
||||||
- script: cargo build -p wasm-bindgen-cli
|
displayName: "install wasm-pack"
|
||||||
- script: ln -snf `pwd`/target/debug/wasm-bindgen $HOME/.cargo/bin/wasm-bindgen
|
- script: |
|
||||||
|
set -ex
|
||||||
|
cargo build -p wasm-bindgen-cli
|
||||||
|
ln -snf `pwd`/target/debug/wasm-bindgen $HOME/.cargo/bin/wasm-bindgen
|
||||||
|
displayName: "install wasm-bindgen for `wasm-pack` to use"
|
||||||
- script: |
|
- script: |
|
||||||
for dir in `ls examples | grep -v README | grep -v asm.js | grep -v raytrace | grep -v without-a-bundler`; do
|
for dir in `ls examples | grep -v README | grep -v asm.js | grep -v raytrace | grep -v without-a-bundler`; do
|
||||||
(cd examples/$dir &&
|
(cd examples/$dir &&
|
||||||
ln -fs ../../node_modules . &&
|
ln -fs ../../node_modules . &&
|
||||||
npm run build -- --output-path $BUILD_ARTIFACTSTAGINGDIRECTORY/exbuild/$dir) || exit 1;
|
npm run build -- --output-path $BUILD_ARTIFACTSTAGINGDIRECTORY/exbuild/$dir) || exit 1;
|
||||||
done
|
done
|
||||||
|
displayName: "build examples"
|
||||||
- task: PublishPipelineArtifact@0
|
- task: PublishPipelineArtifact@0
|
||||||
inputs:
|
inputs:
|
||||||
artifactName: examples1
|
artifactName: examples1
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use proc_macro2::{Ident, Span};
|
use proc_macro2::{Ident, Span};
|
||||||
use std::cell::RefCell;
|
use std::cell::{RefCell, Cell};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@ -28,6 +28,7 @@ struct Interner {
|
|||||||
files: RefCell<HashMap<String, LocalFile>>,
|
files: RefCell<HashMap<String, LocalFile>>,
|
||||||
root: PathBuf,
|
root: PathBuf,
|
||||||
crate_name: String,
|
crate_name: String,
|
||||||
|
has_package_json: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LocalFile {
|
struct LocalFile {
|
||||||
@ -43,6 +44,7 @@ impl Interner {
|
|||||||
files: RefCell::new(HashMap::new()),
|
files: RefCell::new(HashMap::new()),
|
||||||
root: env::var_os("CARGO_MANIFEST_DIR").unwrap().into(),
|
root: env::var_os("CARGO_MANIFEST_DIR").unwrap().into(),
|
||||||
crate_name: env::var("CARGO_PKG_NAME").unwrap(),
|
crate_name: env::var("CARGO_PKG_NAME").unwrap(),
|
||||||
|
has_package_json: Cell::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +69,7 @@ impl Interner {
|
|||||||
if let Some(file) = files.get(id) {
|
if let Some(file) = files.get(id) {
|
||||||
return Ok(self.intern_str(&file.new_identifier))
|
return Ok(self.intern_str(&file.new_identifier))
|
||||||
}
|
}
|
||||||
|
self.check_for_package_json();
|
||||||
let path = if id.starts_with("/") {
|
let path = if id.starts_with("/") {
|
||||||
self.root.join(&id[1..])
|
self.root.join(&id[1..])
|
||||||
} else if id.starts_with("./") || id.starts_with("../") {
|
} else if id.starts_with("./") || id.starts_with("../") {
|
||||||
@ -92,6 +95,16 @@ impl Interner {
|
|||||||
fn unique_crate_identifier(&self) -> String {
|
fn unique_crate_identifier(&self) -> String {
|
||||||
format!("{}-{}", self.crate_name, ShortHash(0))
|
format!("{}-{}", self.crate_name, ShortHash(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_for_package_json(&self) {
|
||||||
|
if self.has_package_json.get() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let path = self.root.join("package.json");
|
||||||
|
if path.exists() {
|
||||||
|
self.has_package_json.set(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shared_program<'a>(
|
fn shared_program<'a>(
|
||||||
@ -144,6 +157,11 @@ fn shared_program<'a>(
|
|||||||
.map(|js| intern.intern_str(js))
|
.map(|js| intern.intern_str(js))
|
||||||
.collect(),
|
.collect(),
|
||||||
unique_crate_identifier: intern.intern_str(&intern.unique_crate_identifier()),
|
unique_crate_identifier: intern.intern_str(&intern.unique_crate_identifier()),
|
||||||
|
package_json: if intern.has_package_json.get() {
|
||||||
|
Some(intern.intern_str(intern.root.join("package.json").to_str().unwrap()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ base64 = "0.9"
|
|||||||
failure = "0.1.2"
|
failure = "0.1.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
rustc-demangle = "0.1.13"
|
rustc-demangle = "0.1.13"
|
||||||
|
serde_json = "1.0"
|
||||||
tempfile = "3.0"
|
tempfile = "3.0"
|
||||||
walrus = "0.5.0"
|
walrus = "0.5.0"
|
||||||
wasm-bindgen-anyref-xform = { path = '../anyref-xform', version = '=0.2.40' }
|
wasm-bindgen-anyref-xform = { path = '../anyref-xform', version = '=0.2.40' }
|
||||||
|
@ -4,6 +4,7 @@ use crate::{Bindgen, EncodeInto, OutputMode};
|
|||||||
use failure::{bail, Error, ResultExt};
|
use failure::{bail, Error, ResultExt};
|
||||||
use std::collections::{HashMap, HashSet, BTreeMap};
|
use std::collections::{HashMap, HashSet, BTreeMap};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
use walrus::{MemoryId, Module};
|
use walrus::{MemoryId, Module};
|
||||||
use wasm_bindgen_wasm_interpreter::Interpreter;
|
use wasm_bindgen_wasm_interpreter::Interpreter;
|
||||||
|
|
||||||
@ -64,6 +65,13 @@ pub struct Context<'a> {
|
|||||||
/// the same `Program`.
|
/// the same `Program`.
|
||||||
pub snippet_offsets: HashMap<&'a str, usize>,
|
pub snippet_offsets: HashMap<&'a str, usize>,
|
||||||
|
|
||||||
|
/// All package.json dependencies we've learned about so far
|
||||||
|
pub package_json_read: HashSet<&'a str>,
|
||||||
|
|
||||||
|
/// A map of the name of npm dependencies we've loaded so far to the path
|
||||||
|
/// they're defined in as well as their version specification.
|
||||||
|
pub npm_dependencies: HashMap<String, (&'a str, String)>,
|
||||||
|
|
||||||
pub anyref: wasm_bindgen_anyref_xform::Context,
|
pub anyref: wasm_bindgen_anyref_xform::Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2509,6 +2517,10 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
self.cx.typescript.push_str("\n\n");
|
self.cx.typescript.push_str("\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(path) = self.program.package_json {
|
||||||
|
self.add_package_json(path)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2980,6 +2992,66 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
let import = self.determine_import(import, item)?;
|
let import = self.determine_import(import, item)?;
|
||||||
Ok(self.cx.import_identifier(import))
|
Ok(self.cx.import_identifier(import))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_package_json(&mut self, path: &'b str) -> Result<(), Error> {
|
||||||
|
if !self.cx.package_json_read.insert(path) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
if !self.cx.config.mode.nodejs() && !self.cx.config.mode.bundler() {
|
||||||
|
bail!("NPM dependencies have been specified in `{}` but \
|
||||||
|
this is only compatible with the `bundler` and `nodejs` targets");
|
||||||
|
}
|
||||||
|
let contents = fs::read_to_string(path).context(format!("failed to read `{}`", path))?;
|
||||||
|
let json: serde_json::Value = serde_json::from_str(&contents)?;
|
||||||
|
let object = match json.as_object() {
|
||||||
|
Some(s) => s,
|
||||||
|
None => bail!(
|
||||||
|
"expected `package.json` to have an JSON object in `{}`",
|
||||||
|
path
|
||||||
|
),
|
||||||
|
};
|
||||||
|
let mut iter = object.iter();
|
||||||
|
let (key, value) = match iter.next() {
|
||||||
|
Some(pair) => pair,
|
||||||
|
None => return Ok(()),
|
||||||
|
};
|
||||||
|
if key != "dependencies" || iter.next().is_some() {
|
||||||
|
bail!(
|
||||||
|
"NPM manifest found at `{}` can currently only have one key, \
|
||||||
|
`dependencies`, and no other fields",
|
||||||
|
path
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let value = match value.as_object() {
|
||||||
|
Some(s) => s,
|
||||||
|
None => bail!("expected `dependencies` to be a JSON object in `{}`", path),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (name, value) in value.iter() {
|
||||||
|
let value = match value.as_str() {
|
||||||
|
Some(s) => s,
|
||||||
|
None => bail!(
|
||||||
|
"keys in `dependencies` are expected to be strings in `{}`",
|
||||||
|
path
|
||||||
|
),
|
||||||
|
};
|
||||||
|
if let Some((prev, _prev_version)) = self.cx.npm_dependencies.get(name) {
|
||||||
|
bail!(
|
||||||
|
"dependency on NPM package `{}` specified in two `package.json` files, \
|
||||||
|
which at the time is not allowed:\n * {}\n * {}",
|
||||||
|
name,
|
||||||
|
path,
|
||||||
|
prev
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cx
|
||||||
|
.npm_dependencies
|
||||||
|
.insert(name.to_string(), (path, value.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Hash, Eq, PartialEq)]
|
#[derive(Hash, Eq, PartialEq)]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-cli-support/0.2")]
|
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-cli-support/0.2")]
|
||||||
|
|
||||||
use failure::{bail, Error, ResultExt};
|
use failure::{bail, Error, ResultExt};
|
||||||
use std::collections::BTreeSet;
|
use std::collections::{BTreeSet, BTreeMap};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
@ -329,6 +329,8 @@ impl Bindgen {
|
|||||||
start: None,
|
start: None,
|
||||||
anyref: Default::default(),
|
anyref: Default::default(),
|
||||||
snippet_offsets: Default::default(),
|
snippet_offsets: Default::default(),
|
||||||
|
npm_dependencies: Default::default(),
|
||||||
|
package_json_read: Default::default(),
|
||||||
};
|
};
|
||||||
cx.anyref.enabled = self.anyref;
|
cx.anyref.enabled = self.anyref;
|
||||||
cx.anyref.prepare(cx.module)?;
|
cx.anyref.prepare(cx.module)?;
|
||||||
@ -366,6 +368,16 @@ impl Bindgen {
|
|||||||
.with_context(|_| format!("failed to write `{}`", path.display()))?;
|
.with_context(|_| format!("failed to write `{}`", path.display()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cx.npm_dependencies.len() > 0 {
|
||||||
|
let map = cx
|
||||||
|
.npm_dependencies
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| (k, &v.1))
|
||||||
|
.collect::<BTreeMap<_, _>>();
|
||||||
|
let json = serde_json::to_string_pretty(&map)?;
|
||||||
|
fs::write(out_dir.join("package.json"), json)?;
|
||||||
|
}
|
||||||
|
|
||||||
cx.finalize(stem)?
|
cx.finalize(stem)?
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -701,4 +713,11 @@ impl OutputMode {
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bundler(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
OutputMode::Bundler { .. } => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,5 +28,9 @@ walrus = "0.5"
|
|||||||
wasm-bindgen-cli-support = { path = "../cli-support", version = "=0.2.40" }
|
wasm-bindgen-cli-support = { path = "../cli-support", version = "=0.2.40" }
|
||||||
wasm-bindgen-shared = { path = "../shared", version = "=0.2.40" }
|
wasm-bindgen-shared = { path = "../shared", version = "=0.2.40" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assert_cmd = "0.11"
|
||||||
|
predicates = "1.0.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
vendored-openssl = ['openssl/vendored']
|
vendored-openssl = ['openssl/vendored']
|
||||||
|
@ -79,7 +79,7 @@ fn main() {
|
|||||||
};
|
};
|
||||||
eprintln!("error: {}", err);
|
eprintln!("error: {}", err);
|
||||||
for cause in err.iter_causes() {
|
for cause in err.iter_causes() {
|
||||||
eprintln!("\tcaused by: {}", cause);
|
eprintln!(" caused by: {}", cause);
|
||||||
}
|
}
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
|
138
crates/cli/tests/wasm-bindgen/main.rs
Normal file
138
crates/cli/tests/wasm-bindgen/main.rs
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
//! A small test suite for the `wasm-bindgen` CLI command itself
|
||||||
|
//!
|
||||||
|
//! This test suite is intended to exercise functionality of the CLI in terms of
|
||||||
|
//! errors and such. It is not intended for comprehensive behavior testing, as
|
||||||
|
//! that should all be placed in the top-level `tests` directory for the
|
||||||
|
//! `wasm-bindgen` crate itself.
|
||||||
|
//!
|
||||||
|
//! Assertions about errors in `wasm-bindgen` or assertions about the output of
|
||||||
|
//! `wasm-bindgen` should all be placed in this test suite, however. Currently
|
||||||
|
//! it is largely based off actually running `cargo build` at test time which is
|
||||||
|
//! quite expensive, so it's recommended that this test suite doesn't become too
|
||||||
|
//! large!
|
||||||
|
|
||||||
|
use assert_cmd::prelude::*;
|
||||||
|
use predicates::str;
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
fn target_dir() -> PathBuf {
|
||||||
|
let mut dir = PathBuf::from(env::current_exe().unwrap());
|
||||||
|
dir.pop(); // current exe
|
||||||
|
if dir.ends_with("deps") {
|
||||||
|
dir.pop();
|
||||||
|
}
|
||||||
|
dir.pop(); // debug and/or release
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn repo_root() -> PathBuf {
|
||||||
|
let mut repo_root = env::current_dir().unwrap();
|
||||||
|
repo_root.pop(); // remove 'cli'
|
||||||
|
repo_root.pop(); // remove 'crates'
|
||||||
|
repo_root
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Project {
|
||||||
|
root: PathBuf,
|
||||||
|
name: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Project {
|
||||||
|
fn new(name: &'static str) -> Project {
|
||||||
|
let root = target_dir().join("cli-tests").join(name);
|
||||||
|
drop(fs::remove_dir_all(&root));
|
||||||
|
fs::create_dir_all(&root).unwrap();
|
||||||
|
Project { root, name }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn file(&mut self, name: &str, contents: &str) -> &mut Project {
|
||||||
|
let dst = self.root.join(name);
|
||||||
|
fs::create_dir_all(dst.parent().unwrap()).unwrap();
|
||||||
|
fs::write(&dst, contents).unwrap();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wasm_bindgen(&mut self, args: &str) -> (Command, PathBuf) {
|
||||||
|
let wasm = self.build();
|
||||||
|
let output = self.root.join("pkg");
|
||||||
|
fs::create_dir_all(&output).unwrap();
|
||||||
|
let mut cmd = Command::cargo_bin("wasm-bindgen").unwrap();
|
||||||
|
cmd.arg("--out-dir").arg(&output);
|
||||||
|
cmd.arg(&wasm);
|
||||||
|
for arg in args.split_whitespace() {
|
||||||
|
cmd.arg(arg);
|
||||||
|
}
|
||||||
|
(cmd, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build(&mut self) -> PathBuf {
|
||||||
|
if !self.root.join("Cargo.toml").is_file() {
|
||||||
|
self.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
&format!(
|
||||||
|
"
|
||||||
|
[package]
|
||||||
|
name = \"{}\"
|
||||||
|
authors = []
|
||||||
|
version = \"1.0.0\"
|
||||||
|
edition = '2018'
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wasm-bindgen = {{ path = '{}' }}
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ['cdylib']
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
",
|
||||||
|
self.name,
|
||||||
|
repo_root().display(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let target_dir = target_dir();
|
||||||
|
Command::new("cargo")
|
||||||
|
.current_dir(&self.root)
|
||||||
|
.arg("build")
|
||||||
|
.arg("--target")
|
||||||
|
.arg("wasm32-unknown-unknown")
|
||||||
|
.env("CARGO_TARGET_DIR", &target_dir)
|
||||||
|
.assert()
|
||||||
|
.success();
|
||||||
|
|
||||||
|
target_dir
|
||||||
|
.join("wasm32-unknown-unknown")
|
||||||
|
.join("debug")
|
||||||
|
.join(self.name)
|
||||||
|
.with_extension("wasm")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn version_useful() {
|
||||||
|
Command::cargo_bin("wasm-bindgen")
|
||||||
|
.unwrap()
|
||||||
|
.arg("-V")
|
||||||
|
.assert()
|
||||||
|
.stdout(str::ends_with("\n"))
|
||||||
|
.stdout(str::starts_with("wasm-bindgen "))
|
||||||
|
.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn works_on_empty_project() {
|
||||||
|
let (mut cmd, _out_dir) = Project::new("works_on_empty_project")
|
||||||
|
.file(
|
||||||
|
"src/lib.rs",
|
||||||
|
r#"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.wasm_bindgen("");
|
||||||
|
cmd.assert().success();
|
||||||
|
}
|
||||||
|
|
||||||
|
mod npm;
|
155
crates/cli/tests/wasm-bindgen/npm.rs
Normal file
155
crates/cli/tests/wasm-bindgen/npm.rs
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_modules_rejects_npm() {
|
||||||
|
let (mut cmd, _out_dir) = Project::new("no_modules_rejects_npm")
|
||||||
|
.file(
|
||||||
|
"src/lib.rs",
|
||||||
|
r#"
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen(module = "foo")]
|
||||||
|
extern {
|
||||||
|
fn foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(start)]
|
||||||
|
pub fn main() {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("package.json", "")
|
||||||
|
.wasm_bindgen("--no-modules");
|
||||||
|
cmd.assert()
|
||||||
|
.stderr("\
|
||||||
|
error: failed to generate bindings for JS import `foo`
|
||||||
|
caused by: import from `foo` module not allowed with `--target no-modules`; use `nodejs`, `web`, or `bundler` target instead
|
||||||
|
")
|
||||||
|
.failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn more_package_json_fields_rejected() {
|
||||||
|
let (mut cmd, _out_dir) = Project::new("more_package_json_fields_rejected")
|
||||||
|
.file(
|
||||||
|
"src/lib.rs",
|
||||||
|
r#"
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen(module = "foo")]
|
||||||
|
extern {
|
||||||
|
fn foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(start)]
|
||||||
|
pub fn main() {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file(
|
||||||
|
"package.json",
|
||||||
|
r#"
|
||||||
|
{
|
||||||
|
"name": "foo",
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.wasm_bindgen("");
|
||||||
|
cmd.assert()
|
||||||
|
.stderr(str::is_match("\
|
||||||
|
error: NPM manifest found at `.*` can currently only have one key, .*
|
||||||
|
").unwrap())
|
||||||
|
.failure();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn npm_conflict_rejected() {
|
||||||
|
let (mut cmd, _out_dir) = Project::new("npm_conflict_rejected")
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
&format!(r#"
|
||||||
|
[package]
|
||||||
|
name = "npm_conflict_rejected"
|
||||||
|
authors = []
|
||||||
|
version = "1.0.0"
|
||||||
|
edition = '2018'
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wasm-bindgen = {{ path = '{}' }}
|
||||||
|
bar = {{ path = 'bar' }}
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ['cdylib']
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
"#,
|
||||||
|
repo_root().display()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.file(
|
||||||
|
"src/lib.rs",
|
||||||
|
r#"
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen(module = "bar")]
|
||||||
|
extern {
|
||||||
|
fn foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(start)]
|
||||||
|
pub fn main() {
|
||||||
|
foo();
|
||||||
|
bar::foo();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file(
|
||||||
|
"package.json",
|
||||||
|
r#"
|
||||||
|
{
|
||||||
|
"dependencies": {"bar": "0.0.0"}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file(
|
||||||
|
"bar/Cargo.toml",
|
||||||
|
&format!(r#"
|
||||||
|
[package]
|
||||||
|
name = "bar"
|
||||||
|
authors = []
|
||||||
|
version = "1.0.0"
|
||||||
|
edition = '2018'
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wasm-bindgen = {{ path = '{}' }}
|
||||||
|
"#,
|
||||||
|
repo_root().display()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.file(
|
||||||
|
"bar/src/lib.rs",
|
||||||
|
r#"
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen(module = "bar")]
|
||||||
|
extern {
|
||||||
|
pub fn foo();
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file(
|
||||||
|
"bar/package.json",
|
||||||
|
r#"
|
||||||
|
{
|
||||||
|
"dependencies": {"bar": "1.0.0"}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.wasm_bindgen("");
|
||||||
|
cmd.assert()
|
||||||
|
.stderr(str::is_match("dependency on NPM package `bar` specified in two").unwrap())
|
||||||
|
.failure();
|
||||||
|
}
|
@ -17,6 +17,7 @@ macro_rules! shared_api {
|
|||||||
local_modules: Vec<LocalModule<'a>>,
|
local_modules: Vec<LocalModule<'a>>,
|
||||||
inline_js: Vec<&'a str>,
|
inline_js: Vec<&'a str>,
|
||||||
unique_crate_identifier: &'a str,
|
unique_crate_identifier: &'a str,
|
||||||
|
package_json: Option<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Import<'a> {
|
struct Import<'a> {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// For more comments about what's going on here, check out the `hello_world`
|
// For more comments about what's going on here, check out the `hello_world`
|
||||||
// example
|
// example
|
||||||
import('./pkg/import_js')
|
import('./crate/pkg/import_js')
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
|
@ -14,7 +14,7 @@ module.exports = {
|
|||||||
template: 'index.html'
|
template: 'index.html'
|
||||||
}),
|
}),
|
||||||
new WasmPackPlugin({
|
new WasmPackPlugin({
|
||||||
crateDirectory: path.resolve(__dirname, ".")
|
crateDirectory: path.resolve(__dirname, "crate")
|
||||||
}),
|
}),
|
||||||
// Have this example work in Edge which doesn't ship `TextEncoder` or
|
// Have this example work in Edge which doesn't ship `TextEncoder` or
|
||||||
// `TextDecoder` at this time.
|
// `TextDecoder` at this time.
|
||||||
|
@ -13,13 +13,13 @@ For example if you're working with this JS file:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
// defined-in-js.js
|
// defined-in-js.js
|
||||||
{{#include ../../../examples/import_js/defined-in-js.js}}
|
{{#include ../../../examples/import_js/crate/defined-in-js.js}}
|
||||||
```
|
```
|
||||||
|
|
||||||
you can use it in Rust with:
|
you can use it in Rust with:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
{{#include ../../../examples/import_js/src/lib.rs}}
|
{{#include ../../../examples/import_js/crate/src/lib.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also [explore the full list of ways to configure imports][attr]
|
You can also [explore the full list of ways to configure imports][attr]
|
||||||
|
Reference in New Issue
Block a user