mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2025-01-08 14:13:51 +03:00
Added example for weather report using rust and webassembly (#2216)
Minor refactoring Updated readme file Updated readme file fixed build error Fixed build error Co-authored-by: Ayush Kumar Mishra <ayush.k.mishra@xcelenergy.com>
This commit is contained in:
parent
1a7d6de1b2
commit
979f0d28bf
23
examples/weather_report/Cargo.toml
Normal file
23
examples/weather_report/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[package]
|
||||||
|
name = "rust-webassembly-weather-reports"
|
||||||
|
description = "Weather Information System- Get the mood of your city on one click using Rust and Webassembly"
|
||||||
|
version = "0.1.1"
|
||||||
|
authors = ["Ayush <ayushmishra2005@gmail.com>"]
|
||||||
|
categories = ["wasm"]
|
||||||
|
readme = "README.md"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
chrono = "0.4.11"
|
||||||
|
reqwest = "0.10.6"
|
||||||
|
wasm-bindgen-futures = "0.4.1"
|
||||||
|
json= "*"
|
||||||
|
wasm-bindgen = "0.2.63"
|
||||||
|
gloo = "0.2.1"
|
||||||
|
|
||||||
|
[dependencies.web-sys]
|
||||||
|
version = "0.3.40"
|
||||||
|
features = ["Document", "Element", "HtmlElement", "Window"]
|
17
examples/weather_report/README.md
Normal file
17
examples/weather_report/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# web-sys: Weather report
|
||||||
|
|
||||||
|
[View documentation for this example online][dox] or [View compiled example
|
||||||
|
online][compiled]
|
||||||
|
|
||||||
|
[compiled]: https://rustwasm.github.io/wasm-bindgen/exbuild/weather_report/
|
||||||
|
[dox]: https://rustwasm.github.io/docs/wasm-bindgen/examples/weather_report.html
|
||||||
|
|
||||||
|
You can build the example locally with:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npm install
|
||||||
|
$ npm run build
|
||||||
|
$ npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
and then visiting http://localhost:8080 in a browser should run the example!
|
BIN
examples/weather_report/assets/images/image.png
Normal file
BIN
examples/weather_report/assets/images/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
BIN
examples/weather_report/assets/images/weather.png
Normal file
BIN
examples/weather_report/assets/images/weather.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 370 KiB |
5831
examples/weather_report/assets/stylesheets/bootstrap.css
vendored
Normal file
5831
examples/weather_report/assets/stylesheets/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
124
examples/weather_report/index.html
Normal file
124
examples/weather_report/index.html
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Weather Information System</title>
|
||||||
|
<link rel="stylesheet" media="screen" href="assets/stylesheets/bootstrap.css">
|
||||||
|
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style data-gr-c-s-loaded="true">
|
||||||
|
<style type="text/css">.ReportStyles-mainDiv {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
background-color: #3D4048;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-heading {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: rgb(220, 208, 192);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-firstSpan {
|
||||||
|
margin-left: 20px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-shadow: 2px 2px 4px #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-secondSpan {
|
||||||
|
text-shadow: 1px 1px 1px #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-firstImg {
|
||||||
|
height: 60px;
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-secondImg {
|
||||||
|
height: 60px;
|
||||||
|
width: 60px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-secondDiv {
|
||||||
|
margin-top: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-search {
|
||||||
|
width: 60%;
|
||||||
|
height: 35px;
|
||||||
|
margin: 0% 0px 0px 16%;
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-bootstrapButton {
|
||||||
|
height: 35px;
|
||||||
|
margin: -1px 0px 0px 0%;
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-mainContainer {
|
||||||
|
margin-top: 30px;
|
||||||
|
border-top: 2px solid #ccc;
|
||||||
|
padding-top: 30px;
|
||||||
|
border-bottom: 2px solid #ccc;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-innerDiv {
|
||||||
|
width: 530px;
|
||||||
|
height: 400px;
|
||||||
|
margin-left: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-city {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #67890a;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-table {
|
||||||
|
width: 540px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-td {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-firstTd {
|
||||||
|
padding: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-secondTd {
|
||||||
|
padding: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ReportStyles-mapCanvas {
|
||||||
|
height: 430px;
|
||||||
|
width: 512px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script src="index.js"></script>
|
||||||
|
<div class=" ReportStyles-mainDiv col-md-12">
|
||||||
|
<h1 class=" ReportStyles-heading">
|
||||||
|
<img class=" ReportStyles-firstImg" src="assets/images/image.png">
|
||||||
|
<span class=" ReportStyles-firstSpan">Weather Report - </span>
|
||||||
|
<span class=" ReportStyles-secondSpan">Get the mood of your city on one click</span>
|
||||||
|
<img class=" ReportStyles-secondImg" src="assets/images/image.png">
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
4
examples/weather_report/index.js
Normal file
4
examples/weather_report/index.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// For more comments about what's going on here, check out the `hello_world`
|
||||||
|
// example
|
||||||
|
import('./pkg')
|
||||||
|
.catch(console.error);
|
14
examples/weather_report/package.json
Normal file
14
examples/weather_report/package.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack",
|
||||||
|
"serve": "webpack-dev-server"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@wasm-tool/wasm-pack-plugin": "1.0.1",
|
||||||
|
"text-encoding": "^0.7.0",
|
||||||
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
"webpack": "^4.29.4",
|
||||||
|
"webpack-cli": "^3.1.1",
|
||||||
|
"webpack-dev-server": "^3.1.0"
|
||||||
|
}
|
||||||
|
}
|
247
examples/weather_report/src/lib.rs
Normal file
247
examples/weather_report/src/lib.rs
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
extern crate chrono;
|
||||||
|
extern crate reqwest;
|
||||||
|
|
||||||
|
use chrono::prelude::DateTime;
|
||||||
|
use chrono::Utc;
|
||||||
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
|
use gloo::events::EventListener;
|
||||||
|
use json::JsonValue;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
use wasm_bindgen::JsCast;
|
||||||
|
use wasm_bindgen_futures::spawn_local;
|
||||||
|
use web_sys::Document;
|
||||||
|
use web_sys::Element;
|
||||||
|
use web_sys::HtmlInputElement;
|
||||||
|
|
||||||
|
#[wasm_bindgen(module = "/util.js")]
|
||||||
|
extern "C" {
|
||||||
|
fn initialize(lat: f64, lon: f64);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(start)]
|
||||||
|
pub fn run() -> Result<(), JsValue> {
|
||||||
|
let window = web_sys::window().expect("no global `window` exists");
|
||||||
|
let document = window.document().expect("should have a document on window");
|
||||||
|
let body = document.body().expect("document should have a body");
|
||||||
|
|
||||||
|
// Manufacture the element we're gonna append
|
||||||
|
let search_div = create_div(&document, "search", "ReportStyles-secondDiv col-md-12");
|
||||||
|
let input_box = create_input_box(&document);
|
||||||
|
search_div.append_child(&input_box)?;
|
||||||
|
let submit_box = create_submit_box(&document);
|
||||||
|
let temp_div = create_div(
|
||||||
|
&document,
|
||||||
|
"tempDetail",
|
||||||
|
"ReportStyles-mainContainer col-md-12 maincontainer",
|
||||||
|
);
|
||||||
|
let first_div = document.create_element("div")?;
|
||||||
|
let second_div = create_div(&document, "second_div", "col-md-6");
|
||||||
|
let third_div = create_div(&document, "third_div", "ReportStyles-innerDiv");
|
||||||
|
let fourth_div = create_div(&document, "cityName", "ReportStyles-city");
|
||||||
|
|
||||||
|
let table_div = document.create_element("table")?;
|
||||||
|
table_div.set_class_name("ReportStyles-table table-bordered table-striped");
|
||||||
|
|
||||||
|
let tbody_div = document.create_element("tbody")?;
|
||||||
|
|
||||||
|
let ftr_div = document.create_element("tr")?;
|
||||||
|
|
||||||
|
let ftd_div = document.create_element("td")?;
|
||||||
|
ftd_div.set_class_name(" ReportStyles-firstTd");
|
||||||
|
|
||||||
|
let img_div = document.create_element("div")?;
|
||||||
|
img_div.set_id("temp");
|
||||||
|
|
||||||
|
let std_div = document.create_element("td")?;
|
||||||
|
std_div.set_class_name(" ReportStyles-secondTd");
|
||||||
|
|
||||||
|
let weather_div = document.create_element("div")?;
|
||||||
|
weather_div.set_id("weather");
|
||||||
|
|
||||||
|
ftr_div.append_child(&ftd_div)?;
|
||||||
|
ftd_div.append_child(&img_div)?;
|
||||||
|
ftr_div.append_child(&std_div)?;
|
||||||
|
std_div.append_child(&weather_div)?;
|
||||||
|
|
||||||
|
let str_div = document.create_element("tr")?;
|
||||||
|
let ptd_div = document.create_element("td")?;
|
||||||
|
ptd_div.set_class_name(" ReportStyles-td");
|
||||||
|
ptd_div.set_inner_html("Pressure");
|
||||||
|
let sptd_div = document.create_element("td")?;
|
||||||
|
sptd_div.set_id("pressure");
|
||||||
|
str_div.append_child(&ptd_div)?;
|
||||||
|
str_div.append_child(&sptd_div)?;
|
||||||
|
|
||||||
|
let ttr_div = document.create_element("tr")?;
|
||||||
|
let htd_div = document.create_element("td")?;
|
||||||
|
htd_div.set_class_name(" ReportStyles-td");
|
||||||
|
htd_div.set_inner_html("Humidity");
|
||||||
|
let shtd_div = document.create_element("td")?;
|
||||||
|
shtd_div.set_id("humidity");
|
||||||
|
ttr_div.append_child(&htd_div)?;
|
||||||
|
ttr_div.append_child(&shtd_div)?;
|
||||||
|
|
||||||
|
let sunr_tr_div = document.create_element("tr")?;
|
||||||
|
let sunr_td_div = document.create_element("td")?;
|
||||||
|
sunr_td_div.set_class_name(" ReportStyles-td");
|
||||||
|
sunr_td_div.set_inner_html("Sunrise[UTC]");
|
||||||
|
let sunr_s_td_div = document.create_element("td")?;
|
||||||
|
sunr_s_td_div.set_id("sunrise");
|
||||||
|
sunr_tr_div.append_child(&sunr_td_div)?;
|
||||||
|
sunr_tr_div.append_child(&sunr_s_td_div)?;
|
||||||
|
|
||||||
|
let suns_tr_div = document.create_element("tr")?;
|
||||||
|
let suns_td_div = document.create_element("td")?;
|
||||||
|
suns_td_div.set_class_name(" ReportStyles-td");
|
||||||
|
suns_td_div.set_inner_html("Sunset[UTC]");
|
||||||
|
let suns_s_td_div = document.create_element("td")?;
|
||||||
|
suns_s_td_div.set_id("sunset");
|
||||||
|
suns_tr_div.append_child(&suns_td_div)?;
|
||||||
|
suns_tr_div.append_child(&suns_s_td_div)?;
|
||||||
|
|
||||||
|
let geo_tr_div = document.create_element("tr")?;
|
||||||
|
let geo_htd_div = document.create_element("td")?;
|
||||||
|
geo_htd_div.set_class_name(" ReportStyles-td");
|
||||||
|
geo_htd_div.set_inner_html("Geo coords");
|
||||||
|
let geo_shtd_div = document.create_element("td")?;
|
||||||
|
geo_shtd_div.set_id("geocoords");
|
||||||
|
geo_tr_div.append_child(&geo_htd_div)?;
|
||||||
|
geo_tr_div.append_child(&geo_shtd_div)?;
|
||||||
|
|
||||||
|
tbody_div.append_child(&ftr_div)?;
|
||||||
|
tbody_div.append_child(&str_div)?;
|
||||||
|
tbody_div.append_child(&ttr_div)?;
|
||||||
|
tbody_div.append_child(&sunr_tr_div)?;
|
||||||
|
tbody_div.append_child(&suns_tr_div)?;
|
||||||
|
tbody_div.append_child(&geo_tr_div)?;
|
||||||
|
|
||||||
|
table_div.append_child(&tbody_div)?;
|
||||||
|
third_div.append_child(&fourth_div)?;
|
||||||
|
third_div.append_child(&table_div)?;
|
||||||
|
|
||||||
|
let map_div = document.create_element("div")?;
|
||||||
|
map_div.set_class_name("col-md-6");
|
||||||
|
let map_canvas_div = document.create_element("div")?;
|
||||||
|
map_canvas_div.set_class_name(" ReportStyles-mapCanvas");
|
||||||
|
map_canvas_div.set_id("map_canvas");
|
||||||
|
map_div.append_child(&map_canvas_div)?;
|
||||||
|
|
||||||
|
second_div.append_child(&third_div)?;
|
||||||
|
first_div.append_child(&second_div)?;
|
||||||
|
first_div.append_child(&map_div)?;
|
||||||
|
|
||||||
|
temp_div.append_child(&first_div)?;
|
||||||
|
search_div.append_child(&submit_box)?;
|
||||||
|
body.append_child(&search_div)?;
|
||||||
|
body.append_child(&temp_div)?;
|
||||||
|
|
||||||
|
let on_click = EventListener::new(&submit_box, "click", move |_event| {
|
||||||
|
let input_value = document
|
||||||
|
.get_element_by_id("name")
|
||||||
|
.unwrap()
|
||||||
|
.dyn_into::<HtmlInputElement>()
|
||||||
|
.unwrap()
|
||||||
|
.value();
|
||||||
|
let temp_d = temp_div.clone();
|
||||||
|
let city = fourth_div.clone();
|
||||||
|
let image = img_div.clone();
|
||||||
|
let weather = weather_div.clone();
|
||||||
|
let pressure = sptd_div.clone();
|
||||||
|
let humidity = shtd_div.clone();
|
||||||
|
let sunrise = sunr_s_td_div.clone();
|
||||||
|
let sunset = suns_s_td_div.clone();
|
||||||
|
let geo = geo_shtd_div.clone();
|
||||||
|
let input_value: &'static _ = Box::leak(Box::new(input_value));
|
||||||
|
let response = get_response(&input_value);
|
||||||
|
spawn_local(async move {
|
||||||
|
let parsed = response.await;
|
||||||
|
let lon = (&parsed["coord"]["lon"]).to_owned().as_f64().unwrap();
|
||||||
|
let lat = (&parsed["coord"]["lat"]).to_owned().as_f64().unwrap();
|
||||||
|
initialize(lat, lon);
|
||||||
|
let city_name: &str = &parsed["name"].to_owned().to_string();
|
||||||
|
let country_name: &str = &parsed["sys"]["country"].to_owned().to_string();
|
||||||
|
let place = [city_name, ",", country_name].concat();
|
||||||
|
let icon = &parsed["weather"][0]["icon"].to_owned().to_string();
|
||||||
|
let src = [
|
||||||
|
"<img src='http://openweathermap.org/img/w/",
|
||||||
|
icon,
|
||||||
|
".png'>",
|
||||||
|
" ",
|
||||||
|
]
|
||||||
|
.concat();
|
||||||
|
let temp = ((&parsed["main"]["temp"]).to_owned().as_f64().unwrap() - 273.15) as i64;
|
||||||
|
|
||||||
|
let content = [src, temp.to_string()].concat();
|
||||||
|
let p: &str = &parsed["main"]["pressure"].to_owned().to_string();
|
||||||
|
let h: &str = &parsed["main"]["humidity"].to_owned().to_string();
|
||||||
|
let sun_r = ((&parsed["sys"]["sunrise"]).to_owned().as_f64().unwrap()) as u64;
|
||||||
|
let sun_s = ((&parsed["sys"]["sunset"]).to_owned().as_f64().unwrap()) as u64;
|
||||||
|
temp_d.set_attribute("style", "display: block");
|
||||||
|
city.set_inner_html(&place);
|
||||||
|
image.set_inner_html(&content);
|
||||||
|
weather.set_inner_html(&parsed["weather"][0]["main"].to_owned().to_string());
|
||||||
|
pressure.set_inner_html(&([p, " hpa"].concat()));
|
||||||
|
humidity.set_inner_html(&([h, "%"].concat()));
|
||||||
|
sunrise.set_inner_html(&get_time(sun_r));
|
||||||
|
sunset.set_inner_html(&get_time(sun_s));
|
||||||
|
geo.set_inner_html(&(["[", &lon.to_string(), ",", &lat.to_string(), "]"].concat()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// When a Closure is dropped it will invalidate the associated JS closure.
|
||||||
|
// Here we want JS callback to be alive for the entire duration of the program.
|
||||||
|
// So we used `forget` leak this instance of Closure.
|
||||||
|
// It should be used sparingly to ensure the memory leak doesn't affect the program too much.
|
||||||
|
on_click.forget();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_div(document: &Document, id: &str, class: &str) -> Element {
|
||||||
|
let div = document.create_element("div").unwrap();
|
||||||
|
div.set_id(id);
|
||||||
|
div.set_class_name(class);
|
||||||
|
div
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_submit_box(document: &Document) -> Element {
|
||||||
|
let submit_box: Element = document.create_element("input").unwrap();
|
||||||
|
submit_box.set_attribute("type", "button");
|
||||||
|
submit_box.set_attribute("value", "Search");
|
||||||
|
submit_box.set_attribute("name", "submit");
|
||||||
|
submit_box.set_id("submit");
|
||||||
|
submit_box.set_class_name(" ReportStyles-bootstrapButton btn btn-info");
|
||||||
|
submit_box
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_input_box(document: &Document) -> Element {
|
||||||
|
let input_box = document.create_element("input").unwrap();
|
||||||
|
input_box.set_attribute("name", "name");
|
||||||
|
input_box.set_attribute("value", "Delhi");
|
||||||
|
input_box.set_attribute("type", "text");
|
||||||
|
input_box.set_attribute("placeholder", "Type city name here");
|
||||||
|
input_box.set_id("name");
|
||||||
|
input_box.set_class_name("ReportStyles-search");
|
||||||
|
input_box
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get response from weather api
|
||||||
|
async fn get_response(location: &str) -> JsonValue {
|
||||||
|
let url1 = "http://api.openweathermap.org/data/2.5/weather?q=";
|
||||||
|
let url2 = "&appid=<apiKey>";
|
||||||
|
|
||||||
|
let url = [url1, location, url2].concat();
|
||||||
|
|
||||||
|
let resp = reqwest::get(&url).await.unwrap().text().await.unwrap();
|
||||||
|
|
||||||
|
json::parse(&resp).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert millisecond into UTC date
|
||||||
|
fn get_time(millis: u64) -> String {
|
||||||
|
let d = UNIX_EPOCH + Duration::from_secs(millis);
|
||||||
|
// Create DateTime from SystemTime
|
||||||
|
let datetime = DateTime::<Utc>::from(d);
|
||||||
|
// Formats the combined date and time with the specified format string.
|
||||||
|
datetime.format("%H:%M:%S").to_string()
|
||||||
|
}
|
16
examples/weather_report/util.js
Normal file
16
examples/weather_report/util.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export function initialize(lat, lon) {
|
||||||
|
var myLatlng = new google.maps.LatLng(lat, lon);
|
||||||
|
var myOptions = {
|
||||||
|
zoom: 3,
|
||||||
|
center: myLatlng,
|
||||||
|
mapTypeId: google.maps.MapTypeId.ROADMAP
|
||||||
|
}
|
||||||
|
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
|
||||||
|
|
||||||
|
var marker = new google.maps.Marker({
|
||||||
|
position: myLatlng,
|
||||||
|
title:"Hello World!"
|
||||||
|
});
|
||||||
|
|
||||||
|
marker.setMap(map);
|
||||||
|
}
|
27
examples/weather_report/webpack.config.js
Normal file
27
examples/weather_report/webpack.config.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: './index.js',
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
filename: 'index.js',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: './index.html'
|
||||||
|
}),
|
||||||
|
new WasmPackPlugin({
|
||||||
|
crateDirectory: path.resolve(__dirname, ".")
|
||||||
|
}),
|
||||||
|
// Have this example work in Edge which doesn't ship `TextEncoder` or
|
||||||
|
// `TextDecoder` at this time.
|
||||||
|
new webpack.ProvidePlugin({
|
||||||
|
TextDecoder: ['text-encoding', 'TextDecoder'],
|
||||||
|
TextEncoder: ['text-encoding', 'TextEncoder']
|
||||||
|
})
|
||||||
|
],
|
||||||
|
mode: 'development'
|
||||||
|
};
|
18
guide/src/examples/weather_report.md
Normal file
18
guide/src/examples/weather_report.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# web-sys: Weather report
|
||||||
|
|
||||||
|
[View full source code][code] or [view the compiled example online][online]
|
||||||
|
|
||||||
|
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/weather_report/
|
||||||
|
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/weather_report
|
||||||
|
|
||||||
|
This example makes an HTTP request to [OpenWeather API](https://openweathermap.org/),
|
||||||
|
parses response in JSON and render UI from that JSON. It also shows the usage of
|
||||||
|
`spawn_local` function for handling asynchronous tasks.
|
||||||
|
|
||||||
|
Please add your api key in *get_response()* before running this application.
|
||||||
|
|
||||||
|
## `src/lib.rs`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
{{#include ../../../examples/weather_report/src/lib.rs}}
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user