mirror of
https://github.com/speice-io/isomorphic-rust
synced 2024-11-23 08:28:32 -05:00
Get most of yew in place
Doesn't actually run though...
This commit is contained in:
parent
65b7367258
commit
ab6e31770d
5
electron_percy_emscripten/app/.gitignore
vendored
5
electron_percy_emscripten/app/.gitignore
vendored
@ -1,5 +0,0 @@
|
|||||||
*.wasm
|
|
||||||
*.bundle.js
|
|
||||||
bundle.js
|
|
||||||
electron_percy_wasm.js
|
|
||||||
app.js
|
|
@ -1,8 +0,0 @@
|
|||||||
import { main } from "./app"
|
|
||||||
|
|
||||||
console.log(main(24))
|
|
||||||
|
|
||||||
console.log("app_loader entrance")
|
|
||||||
let rootNode = document.getElementById('root')
|
|
||||||
//rootNode.parentElement.replaceChild(main(), rootNode)
|
|
||||||
rootNode = document.getElementById('root')
|
|
@ -1,11 +0,0 @@
|
|||||||
#![no_std]
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate stdweb;
|
|
||||||
|
|
||||||
use stdweb::web::Element;
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn main(x: i32) -> i32 {
|
|
||||||
x * 2
|
|
||||||
}
|
|
@ -1,91 +0,0 @@
|
|||||||
function asmFunc(global, env, buffer) {
|
|
||||||
"almost asm";
|
|
||||||
var HEAP8 = new global.Int8Array(buffer);
|
|
||||||
var HEAP16 = new global.Int16Array(buffer);
|
|
||||||
var HEAP32 = new global.Int32Array(buffer);
|
|
||||||
var HEAPU8 = new global.Uint8Array(buffer);
|
|
||||||
var HEAPU16 = new global.Uint16Array(buffer);
|
|
||||||
var HEAPU32 = new global.Uint32Array(buffer);
|
|
||||||
var HEAPF32 = new global.Float32Array(buffer);
|
|
||||||
var HEAPF64 = new global.Float64Array(buffer);
|
|
||||||
var Math_imul = global.Math.imul;
|
|
||||||
var Math_fround = global.Math.fround;
|
|
||||||
var Math_abs = global.Math.abs;
|
|
||||||
var Math_clz32 = global.Math.clz32;
|
|
||||||
var Math_min = global.Math.min;
|
|
||||||
var Math_max = global.Math.max;
|
|
||||||
var Math_floor = global.Math.floor;
|
|
||||||
var Math_ceil = global.Math.ceil;
|
|
||||||
var Math_sqrt = global.Math.sqrt;
|
|
||||||
var abort = env.abort;
|
|
||||||
var nan = global.NaN;
|
|
||||||
var infinity = global.Infinity;
|
|
||||||
var global$0 = 1048576;
|
|
||||||
var global$1 = 1048610;
|
|
||||||
var global$2 = 1048610;
|
|
||||||
var global$3 = 1048576;
|
|
||||||
var i64toi32_i32$HIGH_BITS = 0;
|
|
||||||
function __wasm_call_ctors() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function __wasm_grow_memory(pagesToAdd) {
|
|
||||||
pagesToAdd = pagesToAdd | 0;
|
|
||||||
var oldPages = __wasm_current_memory() | 0;
|
|
||||||
var newPages = oldPages + pagesToAdd | 0;
|
|
||||||
if ((oldPages < newPages) && (newPages < 65535)) {
|
|
||||||
var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));
|
|
||||||
var newHEAP8 = new global.Int8Array(newBuffer);
|
|
||||||
newHEAP8.set(HEAP8);
|
|
||||||
HEAP8 = newHEAP8;
|
|
||||||
HEAP16 = new global.Int16Array(newBuffer);
|
|
||||||
HEAP32 = new global.Int32Array(newBuffer);
|
|
||||||
HEAPU8 = new global.Uint8Array(newBuffer);
|
|
||||||
HEAPU16 = new global.Uint16Array(newBuffer);
|
|
||||||
HEAPU32 = new global.Uint32Array(newBuffer);
|
|
||||||
HEAPF32 = new global.Float32Array(newBuffer);
|
|
||||||
HEAPF64 = new global.Float64Array(newBuffer);
|
|
||||||
buffer = newBuffer;
|
|
||||||
}
|
|
||||||
return oldPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
function __wasm_current_memory() {
|
|
||||||
return buffer.byteLength / 65536 | 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
memory: Object.create(Object.prototype, {
|
|
||||||
grow: {
|
|
||||||
value: __wasm_grow_memory
|
|
||||||
},
|
|
||||||
buffer: {
|
|
||||||
get: function () {
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const memasmFunc = new ArrayBuffer(1114112);
|
|
||||||
const assignasmFunc = (
|
|
||||||
function(mem) {
|
|
||||||
const _mem = new Uint8Array(mem);
|
|
||||||
return function(offset, s) {
|
|
||||||
if (typeof Buffer === 'undefined') {
|
|
||||||
const bytes = atob(s);
|
|
||||||
for (let i = 0; i < bytes.length; i++)
|
|
||||||
_mem[offset + i] = bytes.charCodeAt(i);
|
|
||||||
} else {
|
|
||||||
const bytes = Buffer.from(s, 'base64');
|
|
||||||
for (let i = 0; i < bytes.length; i++)
|
|
||||||
_mem[offset + i] = bytes[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)(memasmFunc);
|
|
||||||
assignasmFunc(1048576, "AWdkYl9sb2FkX3J1c3RfcHJldHR5X3ByaW50ZXJzLnB5AA==");
|
|
||||||
const retasmFunc = asmFunc({Math,Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,NaN,Infinity}, {abort:function() { throw new Error('abort'); }},memasmFunc);
|
|
||||||
export const memory = retasmFunc.memory;
|
|
File diff suppressed because it is too large
Load Diff
4
electron_yew_wasm/app/.gitignore
vendored
4
electron_yew_wasm/app/.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
*.wasm
|
|
||||||
*.bundle.js
|
|
||||||
bundle.js
|
|
||||||
electron_percy_wasm.js
|
|
@ -1,10 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
import * as wasm from './electron_yew_wasm_bg';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
export function main() {
|
|
||||||
return wasm.main();
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
target/
|
target/
|
||||||
binaryen/
|
dist/
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "electron_percy_emscripten"
|
name = "electron_percy_wasm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Bradlee Speice <bradlee@speice.io>"]
|
authors = ["Bradlee Speice <bradlee@speice.io>"]
|
||||||
|
|
||||||
@ -7,4 +7,6 @@ authors = ["Bradlee Speice <bradlee@speice.io>"]
|
|||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
stdweb = "0.4"
|
percy-webapis = "0.0.1"
|
||||||
|
virtual-dom-rs = "0.1"
|
||||||
|
wasm-bindgen = "0.2"
|
372
percy_patched_webpack/WasmMainTemplatePlugin.patched.js
Normal file
372
percy_patched_webpack/WasmMainTemplatePlugin.patched.js
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
/*
|
||||||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
|
Author Tobias Koppers @sokra
|
||||||
|
*/
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const Template = require("../Template");
|
||||||
|
const WebAssemblyUtils = require("./WebAssemblyUtils");
|
||||||
|
|
||||||
|
/** @typedef {import("../Module")} Module */
|
||||||
|
/** @typedef {import("../MainTemplate")} MainTemplate */
|
||||||
|
|
||||||
|
// Get all wasm modules
|
||||||
|
const getAllWasmModules = chunk => {
|
||||||
|
const wasmModules = chunk.getAllAsyncChunks();
|
||||||
|
const array = [];
|
||||||
|
for (const chunk of wasmModules) {
|
||||||
|
for (const m of chunk.modulesIterable) {
|
||||||
|
if (m.type.startsWith("webassembly")) {
|
||||||
|
array.push(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generates the import object function for a module
|
||||||
|
* @param {Module} module the module
|
||||||
|
* @param {boolean} mangle mangle imports
|
||||||
|
* @returns {string} source code
|
||||||
|
*/
|
||||||
|
const generateImportObject = (module, mangle) => {
|
||||||
|
const waitForInstances = new Map();
|
||||||
|
const properties = [];
|
||||||
|
const usedWasmDependencies = WebAssemblyUtils.getUsedDependencies(
|
||||||
|
module,
|
||||||
|
mangle
|
||||||
|
);
|
||||||
|
for (const usedDep of usedWasmDependencies) {
|
||||||
|
const dep = usedDep.dependency;
|
||||||
|
const importedModule = dep.module;
|
||||||
|
const exportName = dep.name;
|
||||||
|
const usedName = importedModule && importedModule.isUsed(exportName);
|
||||||
|
const description = dep.description;
|
||||||
|
const direct = dep.onlyDirectImport;
|
||||||
|
|
||||||
|
const module = usedDep.module;
|
||||||
|
const name = usedDep.name;
|
||||||
|
|
||||||
|
if (direct) {
|
||||||
|
const instanceVar = `m${waitForInstances.size}`;
|
||||||
|
waitForInstances.set(instanceVar, importedModule.id);
|
||||||
|
properties.push({
|
||||||
|
module,
|
||||||
|
name,
|
||||||
|
value: `${instanceVar}[${JSON.stringify(usedName)}]`
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const params = description.signature.params.map(
|
||||||
|
(param, k) => "p" + k + param.valtype
|
||||||
|
);
|
||||||
|
|
||||||
|
const mod = `installedModules[${JSON.stringify(importedModule.id)}]`;
|
||||||
|
const func = `${mod}.exports[${JSON.stringify(usedName)}]`;
|
||||||
|
|
||||||
|
properties.push({
|
||||||
|
module,
|
||||||
|
name,
|
||||||
|
value: Template.asString([
|
||||||
|
(importedModule.type.startsWith("webassembly")
|
||||||
|
? `${mod} ? ${func} : `
|
||||||
|
: "") + `function(${params}) {`,
|
||||||
|
Template.indent([`return ${func}(${params});`]),
|
||||||
|
"}"
|
||||||
|
])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let importObject;
|
||||||
|
if (mangle) {
|
||||||
|
importObject = [
|
||||||
|
"return {",
|
||||||
|
Template.indent([
|
||||||
|
properties.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n")
|
||||||
|
]),
|
||||||
|
"};"
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
const propertiesByModule = new Map();
|
||||||
|
for (const p of properties) {
|
||||||
|
let list = propertiesByModule.get(p.module);
|
||||||
|
if (list === undefined) {
|
||||||
|
propertiesByModule.set(p.module, (list = []));
|
||||||
|
}
|
||||||
|
list.push(p);
|
||||||
|
}
|
||||||
|
importObject = [
|
||||||
|
"return {",
|
||||||
|
Template.indent([
|
||||||
|
Array.from(propertiesByModule, ([module, list]) => {
|
||||||
|
return Template.asString([
|
||||||
|
`${JSON.stringify(module)}: {`,
|
||||||
|
Template.indent([
|
||||||
|
list.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n")
|
||||||
|
]),
|
||||||
|
"}"
|
||||||
|
]);
|
||||||
|
}).join(",\n")
|
||||||
|
]),
|
||||||
|
"};"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waitForInstances.size === 1) {
|
||||||
|
const moduleId = Array.from(waitForInstances.values())[0];
|
||||||
|
const promise = `installedWasmModules[${JSON.stringify(moduleId)}]`;
|
||||||
|
const variable = Array.from(waitForInstances.keys())[0];
|
||||||
|
return Template.asString([
|
||||||
|
`${JSON.stringify(module.id)}: function() {`,
|
||||||
|
Template.indent([
|
||||||
|
`return promiseResolve().then(function() { return ${promise}; }).then(function(${variable}) {`,
|
||||||
|
Template.indent(importObject),
|
||||||
|
"});"
|
||||||
|
]),
|
||||||
|
"},"
|
||||||
|
]);
|
||||||
|
} else if (waitForInstances.size > 0) {
|
||||||
|
const promises = Array.from(
|
||||||
|
waitForInstances.values(),
|
||||||
|
id => `installedWasmModules[${JSON.stringify(id)}]`
|
||||||
|
).join(", ");
|
||||||
|
const variables = Array.from(
|
||||||
|
waitForInstances.keys(),
|
||||||
|
(name, i) => `${name} = array[${i}]`
|
||||||
|
).join(", ");
|
||||||
|
return Template.asString([
|
||||||
|
`${JSON.stringify(module.id)}: function() {`,
|
||||||
|
Template.indent([
|
||||||
|
`return promiseResolve().then(function() { return Promise.all([${promises}]); }).then(function(array) {`,
|
||||||
|
Template.indent([`var ${variables};`, ...importObject]),
|
||||||
|
"});"
|
||||||
|
]),
|
||||||
|
"},"
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return Template.asString([
|
||||||
|
`${JSON.stringify(module.id)}: function() {`,
|
||||||
|
Template.indent(importObject),
|
||||||
|
"},"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class WasmMainTemplatePlugin {
|
||||||
|
constructor({ generateLoadBinaryCode, supportsStreaming, mangleImports }) {
|
||||||
|
this.generateLoadBinaryCode = generateLoadBinaryCode;
|
||||||
|
this.supportsStreaming = supportsStreaming;
|
||||||
|
this.mangleImports = mangleImports;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MainTemplate} mainTemplate main template
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
apply(mainTemplate) {
|
||||||
|
mainTemplate.hooks.localVars.tap(
|
||||||
|
"WasmMainTemplatePlugin",
|
||||||
|
(source, chunk) => {
|
||||||
|
const wasmModules = getAllWasmModules(chunk);
|
||||||
|
if (wasmModules.length === 0) return source;
|
||||||
|
const importObjects = wasmModules.map(module => {
|
||||||
|
return generateImportObject(module, this.mangleImports);
|
||||||
|
});
|
||||||
|
return Template.asString([
|
||||||
|
source,
|
||||||
|
"",
|
||||||
|
"// object to store loaded and loading wasm modules",
|
||||||
|
"var installedWasmModules = {};",
|
||||||
|
"",
|
||||||
|
// This function is used to delay reading the installed wasm module promises
|
||||||
|
// by a microtask. Sorting them doesn't help because there are egdecases where
|
||||||
|
// sorting is not possible (modules splitted into different chunks).
|
||||||
|
// So we not even trying and solve this by a microtask delay.
|
||||||
|
"function promiseResolve() { return Promise.resolve(); }",
|
||||||
|
"",
|
||||||
|
"var wasmImportObjects = {",
|
||||||
|
Template.indent(importObjects),
|
||||||
|
"};"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
mainTemplate.hooks.requireEnsure.tap(
|
||||||
|
"WasmMainTemplatePlugin",
|
||||||
|
(source, chunk, hash) => {
|
||||||
|
const webassemblyModuleFilename =
|
||||||
|
mainTemplate.outputOptions.webassemblyModuleFilename;
|
||||||
|
|
||||||
|
const chunkModuleMaps = chunk.getChunkModuleMaps(m =>
|
||||||
|
m.type.startsWith("webassembly")
|
||||||
|
);
|
||||||
|
if (Object.keys(chunkModuleMaps.id).length === 0) return source;
|
||||||
|
const wasmModuleSrcPath = mainTemplate.getAssetPath(
|
||||||
|
JSON.stringify(webassemblyModuleFilename),
|
||||||
|
{
|
||||||
|
hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
|
||||||
|
hashWithLength: length =>
|
||||||
|
`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
|
||||||
|
module: {
|
||||||
|
id: '" + wasmModuleId + "',
|
||||||
|
hash: `" + ${JSON.stringify(
|
||||||
|
chunkModuleMaps.hash
|
||||||
|
)}[wasmModuleId] + "`,
|
||||||
|
hashWithLength(length) {
|
||||||
|
const shortChunkHashMap = Object.create(null);
|
||||||
|
for (const wasmModuleId of Object.keys(chunkModuleMaps.hash)) {
|
||||||
|
if (typeof chunkModuleMaps.hash[wasmModuleId] === "string") {
|
||||||
|
shortChunkHashMap[wasmModuleId] = chunkModuleMaps.hash[
|
||||||
|
wasmModuleId
|
||||||
|
].substr(0, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return `" + ${JSON.stringify(
|
||||||
|
shortChunkHashMap
|
||||||
|
)}[wasmModuleId] + "`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const createImportObject = content =>
|
||||||
|
this.mangleImports
|
||||||
|
? `{ ${JSON.stringify(
|
||||||
|
WebAssemblyUtils.MANGLED_MODULE
|
||||||
|
)}: ${content} }`
|
||||||
|
: content;
|
||||||
|
return Template.asString([
|
||||||
|
source,
|
||||||
|
"",
|
||||||
|
"// Fetch + compile chunk loading for webassembly",
|
||||||
|
"",
|
||||||
|
`var wasmModules = ${JSON.stringify(
|
||||||
|
chunkModuleMaps.id
|
||||||
|
)}[chunkId] || [];`,
|
||||||
|
"",
|
||||||
|
"wasmModules.forEach(function(wasmModuleId) {",
|
||||||
|
Template.indent([
|
||||||
|
"var installedWasmModuleData = installedWasmModules[wasmModuleId];",
|
||||||
|
"",
|
||||||
|
'// a Promise means "currently loading" or "already loaded".',
|
||||||
|
"if(installedWasmModuleData)",
|
||||||
|
Template.indent(["promises.push(installedWasmModuleData);"]),
|
||||||
|
"else {",
|
||||||
|
Template.indent([
|
||||||
|
`var importObject = wasmImportObjects[wasmModuleId]();`,
|
||||||
|
`var req = ${this.generateLoadBinaryCode(wasmModuleSrcPath)};`,
|
||||||
|
"var promise;",
|
||||||
|
this.supportsStreaming
|
||||||
|
? Template.asString([
|
||||||
|
"if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {",
|
||||||
|
Template.indent([
|
||||||
|
"promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {",
|
||||||
|
Template.indent([
|
||||||
|
`return WebAssembly.instantiate(items[0], ${createImportObject(
|
||||||
|
"items[1]"
|
||||||
|
)});`
|
||||||
|
]),
|
||||||
|
"});"
|
||||||
|
]),
|
||||||
|
"} else if(typeof WebAssembly.instantiateStreaming === 'function') {",
|
||||||
|
Template.indent([
|
||||||
|
`promise = WebAssembly.instantiateStreaming(req, ${createImportObject(
|
||||||
|
"importObject"
|
||||||
|
)}).catch(function(reason) {`,
|
||||||
|
Template.indent([
|
||||||
|
`if (reason.name === "TypeError") {`,
|
||||||
|
Template.indent([
|
||||||
|
`console.log("Potential WASM MIME issue detected, falling back to arrayBuffer instantiation");`,
|
||||||
|
"return req.then(function(x) { return x.arrayBuffer(); }).then(function(bytes) {",
|
||||||
|
Template.indent([
|
||||||
|
"return WebAssembly.instantiate(bytes, importObject);"
|
||||||
|
]),
|
||||||
|
"});"
|
||||||
|
]),
|
||||||
|
"}",
|
||||||
|
"throw reason;"
|
||||||
|
]),
|
||||||
|
"});"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
: Template.asString([
|
||||||
|
"if(importObject instanceof Promise) {",
|
||||||
|
Template.indent([
|
||||||
|
"var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });",
|
||||||
|
"promise = Promise.all([",
|
||||||
|
Template.indent([
|
||||||
|
"bytesPromise.then(function(bytes) { return WebAssembly.compile(bytes); }),",
|
||||||
|
"importObject"
|
||||||
|
]),
|
||||||
|
"]).then(function(items) {",
|
||||||
|
Template.indent([
|
||||||
|
`return WebAssembly.instantiate(items[0], ${createImportObject(
|
||||||
|
"items[1]"
|
||||||
|
)});`
|
||||||
|
]),
|
||||||
|
"});"
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
"} else {",
|
||||||
|
Template.indent([
|
||||||
|
"var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });",
|
||||||
|
"promise = bytesPromise.then(function(bytes) {",
|
||||||
|
Template.indent([
|
||||||
|
`return WebAssembly.instantiate(bytes, ${createImportObject(
|
||||||
|
"importObject"
|
||||||
|
)});`
|
||||||
|
]),
|
||||||
|
"});"
|
||||||
|
]),
|
||||||
|
"}",
|
||||||
|
"promises.push(installedWasmModules[wasmModuleId] = promise.then(function(res) {",
|
||||||
|
Template.indent([
|
||||||
|
`return ${
|
||||||
|
mainTemplate.requireFn
|
||||||
|
}.w[wasmModuleId] = (res.instance || res).exports;`
|
||||||
|
]),
|
||||||
|
"}));"
|
||||||
|
]),
|
||||||
|
"}"
|
||||||
|
]),
|
||||||
|
"});"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
mainTemplate.hooks.requireExtensions.tap(
|
||||||
|
"WasmMainTemplatePlugin",
|
||||||
|
(source, chunk) => {
|
||||||
|
if (!chunk.hasModuleInGraph(m => m.type.startsWith("webassembly"))) {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
return Template.asString([
|
||||||
|
source,
|
||||||
|
"",
|
||||||
|
"// object with all WebAssembly.instance exports",
|
||||||
|
`${mainTemplate.requireFn}.w = {};`
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
mainTemplate.hooks.hash.tap("WasmMainTemplatePlugin", hash => {
|
||||||
|
hash.update("WasmMainTemplatePlugin");
|
||||||
|
hash.update("1");
|
||||||
|
hash.update(`${mainTemplate.outputOptions.webassemblyModuleFilename}`);
|
||||||
|
hash.update(`${this.mangleImports}`);
|
||||||
|
});
|
||||||
|
mainTemplate.hooks.hashForChunk.tap(
|
||||||
|
"WasmMainTemplatePlugin",
|
||||||
|
(hash, chunk) => {
|
||||||
|
const chunkModuleMaps = chunk.getChunkModuleMaps(m =>
|
||||||
|
m.type.startsWith("webassembly")
|
||||||
|
);
|
||||||
|
hash.update(JSON.stringify(chunkModuleMaps.id));
|
||||||
|
const wasmModules = getAllWasmModules(chunk);
|
||||||
|
for (const module of wasmModules) {
|
||||||
|
hash.update(module.hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = WasmMainTemplatePlugin;
|
@ -1,19 +1,12 @@
|
|||||||
#!/bin/bash
|
|
||||||
DIR="$(dirname $0)"
|
DIR="$(dirname $0)"
|
||||||
WASM_DIR="$DIR/target/wasm32-unknown-unknown"
|
WASM_DIR="$DIR/target/wasm32-unknown-unknown"
|
||||||
WASM_NAME="$(cat "$DIR/Cargo.toml" | grep name | sed 's/name = "//' | sed 's/"//g')"
|
WASM_NAME="$(cat "$DIR/Cargo.toml" | grep name | sed 's/name = "//' | sed 's/"//g')"
|
||||||
APP_DIR="$DIR/app/"
|
APP_DIR="$DIR/dist/"
|
||||||
|
|
||||||
if [ ! -f "$DIR/binaryen/bin/wasm2js" ]; then
|
|
||||||
git clone https://github.com/WebAssembly/binaryen "$DIR/binaryen"
|
|
||||||
pushd "$DIR/binaryen"
|
|
||||||
cmake . && make -j8
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d "$APP_DIR" ]; then
|
if [ ! -d "$APP_DIR" ]; then
|
||||||
mkdir "$APP_DIR"
|
mkdir "$APP_DIR"
|
||||||
fi
|
fi
|
||||||
|
cp "$DIR/static/"* "$APP_DIR"
|
||||||
|
|
||||||
if [ -z "$(which cargo)" ]; then
|
if [ -z "$(which cargo)" ]; then
|
||||||
echo 'Must install `cargo` before proceeding. Please see https://rustup.rs/ for more information.'
|
echo 'Must install `cargo` before proceeding. Please see https://rustup.rs/ for more information.'
|
||||||
@ -25,6 +18,10 @@ if [ -z "$(which wasm-bindgen)" ]; then
|
|||||||
cargo install wasm-bindgen-cli
|
cargo install wasm-bindgen-cli
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Patch from: https://github.com/webpack/webpack/pull/7983
|
||||||
|
cp "$DIR/WasmMainTemplatePlugin.patched.js" "$DIR/node_modules/webpack/lib/wasm/WasmMainTemplatePlugin.js"
|
||||||
|
|
||||||
cargo +nightly build --target=wasm32-unknown-unknown && \
|
cargo +nightly build --target=wasm32-unknown-unknown && \
|
||||||
"$DIR/binaryen/bin/wasm2js" --pedantic "$WASM_DIR/debug/$WASM_NAME.wasm" -o "$WASM_DIR/debug/$WASM_NAME.js" && \
|
wasm-bindgen "$WASM_DIR/debug/$WASM_NAME.wasm" --out-dir "$APP_DIR" --no-typescript && \
|
||||||
"$DIR/node_modules/webpack-cli/bin/cli.js" "$WASM_DIR/debug/$WASM_NAME.js" -o "$APP_DIR/app.js"
|
# Still doesn't work with mode=production, not sure why
|
||||||
|
"$DIR/node_modules/webpack-cli/bin/cli.js" --mode=production "$APP_DIR/app_loader.js" -o "$APP_DIR/bundle.js"
|
@ -3,9 +3,9 @@
|
|||||||
"productName": "electron_percy_wasm",
|
"productName": "electron_percy_wasm",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "My Electron application description",
|
"description": "My Electron application description",
|
||||||
"main": "app/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prestart": "./build_wasm.sh",
|
"prestart": "./build.sh",
|
||||||
"start": "electron-forge start",
|
"start": "electron-forge start",
|
||||||
"package": "electron-forge package",
|
"package": "electron-forge package",
|
||||||
"make": "electron-forge make",
|
"make": "electron-forge make",
|
20
percy_patched_webpack/src/lib.rs
Normal file
20
percy_patched_webpack/src/lib.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate virtual_dom_rs;
|
||||||
|
|
||||||
|
extern crate percy_webapis;
|
||||||
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
|
use percy_webapis::log;
|
||||||
|
use percy_webapis::Element;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn main() -> Element {
|
||||||
|
log("Entered Rust code");
|
||||||
|
|
||||||
|
let elem = html! {
|
||||||
|
<span> {"It is alive!"} </span>
|
||||||
|
};
|
||||||
|
|
||||||
|
elem.create_element()
|
||||||
|
}
|
5
percy_patched_webpack/static/app.js
Normal file
5
percy_patched_webpack/static/app.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { main } from "./electron_percy_wasm"
|
||||||
|
|
||||||
|
let rootNode = document.getElementById('root')
|
||||||
|
rootNode.parentElement.replaceChild(main(), rootNode)
|
||||||
|
rootNode = document.getElementById('root')
|
7
percy_patched_webpack/static/app_loader.js
Normal file
7
percy_patched_webpack/static/app_loader.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const app = import("./app")
|
||||||
|
app.then(() => {
|
||||||
|
console.log("Finished resolving application bundle")
|
||||||
|
}, (e) => {
|
||||||
|
console.log("Unable to resolve application bundle: ")
|
||||||
|
console.log(e)
|
||||||
|
})
|
@ -1,3 +1,4 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
target/
|
target/
|
||||||
|
dist/
|
@ -1,11 +1,12 @@
|
|||||||
DIR="$(dirname $0)"
|
DIR="$(dirname $0)"
|
||||||
WASM_DIR="$DIR/target/wasm32-unknown-unknown"
|
WASM_DIR="$DIR/target/wasm32-unknown-unknown"
|
||||||
WASM_NAME="$(cat "$DIR/Cargo.toml" | grep name | sed 's/name = "//' | sed 's/"//g')"
|
WASM_NAME="$(cat "$DIR/Cargo.toml" | grep name | sed 's/name = "//' | sed 's/"//g')"
|
||||||
APP_DIR="$DIR/app/"
|
APP_DIR="$DIR/dist/"
|
||||||
|
|
||||||
if [ ! -d "$APP_DIR" ]; then
|
if [ ! -d "$APP_DIR" ]; then
|
||||||
mkdir "$APP_DIR"
|
mkdir "$APP_DIR"
|
||||||
fi
|
fi
|
||||||
|
cp "$DIR/static/"* "$APP_DIR"
|
||||||
|
|
||||||
if [ -z "$(which cargo)" ]; then
|
if [ -z "$(which cargo)" ]; then
|
||||||
echo 'Must install `cargo` before proceeding. Please see https://rustup.rs/ for more information.'
|
echo 'Must install `cargo` before proceeding. Please see https://rustup.rs/ for more information.'
|
||||||
@ -17,9 +18,8 @@ if [ -z "$(which wasm-bindgen)" ]; then
|
|||||||
cargo install wasm-bindgen-cli
|
cargo install wasm-bindgen-cli
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cargo web build --target=wasm32-unknown-unknown && \
|
cargo +nightly build --target=wasm32-unknown-unknown && \
|
||||||
wasm-bindgen "$WASM_DIR/debug/$WASM_NAME.wasm" --out-dir "$APP_DIR" --no-typescript && \
|
wasm-bindgen "$WASM_DIR/debug/$WASM_NAME.wasm" --out-dir "$APP_DIR" --no-typescript && \
|
||||||
# Have to use --mode=development so we can patch out the call to instantiateStreaming
|
# Have to use --mode=development so we can patch out the call to instantiateStreaming
|
||||||
"$DIR/node_modules/webpack-cli/bin/cli.js" --mode=development "$APP_DIR/app_loader.js" -o "$APP_DIR/bundle.js"
|
"$DIR/node_modules/webpack-cli/bin/cli.js" --mode=development "$APP_DIR/app_loader.js" -o "$APP_DIR/bundle.js" && \
|
||||||
# Necessitated by https://github.com/webpack/webpack/issues/7918
|
sed -i 's/.*instantiateStreaming.*//g' "$APP_DIR/bundle.js"
|
||||||
sed -i '/.*instantiateStreaming.*/d' "$APP_DIR/bundle.js"
|
|
@ -3,9 +3,9 @@
|
|||||||
"productName": "electron_percy_wasm",
|
"productName": "electron_percy_wasm",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "My Electron application description",
|
"description": "My Electron application description",
|
||||||
"main": "app/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prestart": "./build_wasm_bundle.sh",
|
"prestart": "./build.sh",
|
||||||
"start": "electron-forge start",
|
"start": "electron-forge start",
|
||||||
"package": "electron-forge package",
|
"package": "electron-forge package",
|
||||||
"make": "electron-forge make",
|
"make": "electron-forge make",
|
@ -1,14 +1,10 @@
|
|||||||
#[macro_use]
|
|
||||||
extern crate stdweb;
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate yew;
|
extern crate yew;
|
||||||
|
|
||||||
use stdweb::console;
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
type Context = ();
|
|
||||||
struct Model {}
|
struct Model {}
|
||||||
enum Msg {
|
enum Msg {
|
||||||
}
|
}
|
||||||
@ -37,9 +33,8 @@ impl Renderable<Model> for Model {
|
|||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
console!(log, "Entered Rust code");
|
|
||||||
yew::initialize();
|
yew::initialize();
|
||||||
//let app: App<Model> = App::new(());
|
let app: App<Model> = App::new();
|
||||||
//app.mount_to_body();
|
app.mount_to_body();
|
||||||
yew::run_loop();
|
yew::run_loop();
|
||||||
}
|
}
|
@ -7,5 +7,5 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="root">Loading...</div>
|
<div id="root">Loading...</div>
|
||||||
</body>
|
</body>
|
||||||
<script src="./app_loader.js"/>
|
<script src="./bundle.js"/>
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue
Block a user