mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-15 22:11:23 +00:00
Merge pull request #1305 from alexcrichton/npm-dependencies
Implement transitive support for NPM dependencies
This commit is contained in:
@ -4,6 +4,7 @@ use crate::{Bindgen, EncodeInto, OutputMode};
|
||||
use failure::{bail, Error, ResultExt};
|
||||
use std::collections::{HashMap, HashSet, BTreeMap};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use walrus::{MemoryId, Module};
|
||||
use wasm_bindgen_wasm_interpreter::Interpreter;
|
||||
|
||||
@ -64,6 +65,13 @@ pub struct Context<'a> {
|
||||
/// the same `Program`.
|
||||
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,
|
||||
}
|
||||
|
||||
@ -2509,6 +2517,10 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
self.cx.typescript.push_str("\n\n");
|
||||
}
|
||||
|
||||
if let Some(path) = self.program.package_json {
|
||||
self.add_package_json(path)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -2980,6 +2992,66 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
let import = self.determine_import(import, item)?;
|
||||
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)]
|
||||
|
Reference in New Issue
Block a user