4

After compiling some rust code to webassembly using wasm-pack with the option --target browser (the default), I get the following files in typescript/deps/ed25519xp:

  • ed25519xp_bg.wasm
  • ed25519xp_bg.d.ts
  • ed25519xp.d.ts
  • ed25519xp.js
  • package.json

My typescript file looks the following:

// typescript/src/index.ts

export { seed_from_phrase, gen_keypair } from "ed25519xp";

My package.json like this:

{
  "name": "ed25519",
  "version": "0.1.0",
  "description": "ed25519",
  "main": "typescript/dist/bundle.js",
  "types": "typescript/src/index.ts",
  "dependencies": {
    "ed25519xp": "file:typescript/deps/ed25519xp"
  },
  "devDependencies": {
    "@types/node": "^13.7.1",
    "typescript": "^3.7.5",
    "@rollup/plugin-commonjs": "^11.0.2",
    "@rollup/plugin-multi-entry": "^3.0.0",
    "@rollup/plugin-node-resolve": "^7.1.1",
    "@rollup/plugin-wasm": "^3.0.0",
    "rollup": "^1.31.1",
    "rollup-plugin-typescript2": "^0.26.0"
  }
}

And my rollup config looks like this:

// rollup.config.js
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "rollup-plugin-typescript2";
import multi from "@rollup/plugin-multi-entry";
import wasm from "@rollup/plugin-wasm";

export default {
  input: [
    "typescript/deps/ed25519xp/ed25519xp_bg.wasm",
    `typescript/src/index.ts`
  ],
  output: {
    sourcemap: true,
    format: "iife",
    name: "ed25519",
    file: `typescript/dist/bundle.js`
  },
  plugins: [
    multi(),
    resolve({
      browser: true,
      extensions: [".js", ".ts", ".wasm"]
    }),
    commonjs({
      include: [
        `typescript/**/*.js`,
        `typescript/**/*.ts`,
        `typescript/**/*.wasm`,
        "node_modules/**"
      ]
    }),
    typescript(),
    wasm()

    // If we're building for prod (npm run build
    // instead of npm run dev), minify
    // terser()
  ]
};

When I run the command to bundle with rollup (node node_modules/.bin/rollup -c), I get the following error:

(!) Missing exports
https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module
typescript/deps/ed25519xp/ed25519xp.js
memory is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
29: let cachegetUint8Memory0 = null;
30: function getUint8Memory0() {
31:     if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
                                                                                  ^
32:         cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
33:     }
typescript/deps/ed25519xp/ed25519xp.js
memory is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
30: function getUint8Memory0() {
31:     if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
32:         cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
                                                       ^
33:     }
34:     return cachegetUint8Memory0;
typescript/deps/ed25519xp/ed25519xp.js
memory is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
30: function getUint8Memory0() {
31:     if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
32:         cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
                                                       ^
33:     }
34:     return cachegetUint8Memory0;
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_malloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
107: */
108: export function gen_keypair(phrase) {
109:     var ptr0 = passStringToWasm0(phrase, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
                                                   ^
110:     var len0 = WASM_VECTOR_LEN;
111:     var ret = wasm.gen_keypair(ptr0, len0);
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_realloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
107: */
108: export function gen_keypair(phrase) {
109:     var ptr0 = passStringToWasm0(phrase, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
                                                                           ^
110:     var len0 = WASM_VECTOR_LEN;
111:     var ret = wasm.gen_keypair(ptr0, len0);
typescript/deps/ed25519xp/ed25519xp.js
gen_keypair is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
109:     var ptr0 = passStringToWasm0(phrase, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
110:     var len0 = WASM_VECTOR_LEN;
111:     var ret = wasm.gen_keypair(ptr0, len0);
                        ^
112:     return takeObject(ret);
113: }
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_malloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
124: */
125: export function pubKey_from_pair_bytes(pair_bytes) {
126:     var ptr0 = passArray8ToWasm0(pair_bytes, wasm.__wbindgen_malloc);
                                                       ^
127:     var len0 = WASM_VECTOR_LEN;
128:     var ret = wasm.pubKey_from_pair_bytes(ptr0, len0);
typescript/deps/ed25519xp/ed25519xp.js
pubKey_from_pair_bytes is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
126:     var ptr0 = passArray8ToWasm0(pair_bytes, wasm.__wbindgen_malloc);
127:     var len0 = WASM_VECTOR_LEN;
128:     var ret = wasm.pubKey_from_pair_bytes(ptr0, len0);
                        ^
129:     return takeObject(ret);
130: }
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_malloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
136: */
137: export function sign(message, keypair_bytes) {
138:     var ptr0 = passArray8ToWasm0(message, wasm.__wbindgen_malloc);
                                                    ^
139:     var len0 = WASM_VECTOR_LEN;
140:     var ptr1 = passArray8ToWasm0(keypair_bytes, wasm.__wbindgen_malloc);
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_malloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
138:     var ptr0 = passArray8ToWasm0(message, wasm.__wbindgen_malloc);
139:     var len0 = WASM_VECTOR_LEN;
140:     var ptr1 = passArray8ToWasm0(keypair_bytes, wasm.__wbindgen_malloc);
                                                          ^
141:     var len1 = WASM_VECTOR_LEN;
142:     var ret = wasm.sign(ptr0, len0, ptr1, len1);
typescript/deps/ed25519xp/ed25519xp.js
sign is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
140:     var ptr1 = passArray8ToWasm0(keypair_bytes, wasm.__wbindgen_malloc);
141:     var len1 = WASM_VECTOR_LEN;
142:     var ret = wasm.sign(ptr0, len0, ptr1, len1);
                        ^
143:     return takeObject(ret);
144: }
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_malloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
151: */
152: export function verify(message, pubKey_bytes, sig_bytes) {
153:     var ptr0 = passArray8ToWasm0(message, wasm.__wbindgen_malloc);
                                                    ^
154:     var len0 = WASM_VECTOR_LEN;
155:     var ptr1 = passArray8ToWasm0(pubKey_bytes, wasm.__wbindgen_malloc);
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_malloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
153:     var ptr0 = passArray8ToWasm0(message, wasm.__wbindgen_malloc);
154:     var len0 = WASM_VECTOR_LEN;
155:     var ptr1 = passArray8ToWasm0(pubKey_bytes, wasm.__wbindgen_malloc);
                                                         ^
156:     var len1 = WASM_VECTOR_LEN;
157:     var ptr2 = passArray8ToWasm0(sig_bytes, wasm.__wbindgen_malloc);
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_malloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
155:     var ptr1 = passArray8ToWasm0(pubKey_bytes, wasm.__wbindgen_malloc);
156:     var len1 = WASM_VECTOR_LEN;
157:     var ptr2 = passArray8ToWasm0(sig_bytes, wasm.__wbindgen_malloc);
                                                      ^
158:     var len2 = WASM_VECTOR_LEN;
159:     var ret = wasm.verify(ptr0, len0, ptr1, len1, ptr2, len2);
typescript/deps/ed25519xp/ed25519xp.js
verify is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
157:     var ptr2 = passArray8ToWasm0(sig_bytes, wasm.__wbindgen_malloc);
158:     var len2 = WASM_VECTOR_LEN;
159:     var ret = wasm.verify(ptr0, len0, ptr1, len1, ptr2, len2);
                        ^
160:     return ret !== 0;
161: }
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_malloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
166: */
167: export function seed_from_phrase(phrase) {
168:     var ptr0 = passStringToWasm0(phrase, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
                                                   ^
169:     var len0 = WASM_VECTOR_LEN;
170:     var ret = wasm.seed_from_phrase(ptr0, len0);
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_realloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
166: */
167: export function seed_from_phrase(phrase) {
168:     var ptr0 = passStringToWasm0(phrase, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
                                                                           ^
169:     var len0 = WASM_VECTOR_LEN;
170:     var ret = wasm.seed_from_phrase(ptr0, len0);
typescript/deps/ed25519xp/ed25519xp.js
seed_from_phrase is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
168:     var ptr0 = passStringToWasm0(phrase, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
169:     var len0 = WASM_VECTOR_LEN;
170:     var ret = wasm.seed_from_phrase(ptr0, len0);
                        ^
171:     return takeObject(ret);
172: }
typescript/deps/ed25519xp/ed25519xp.js
memory is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
174: let cachegetInt32Memory0 = null;
175: function getInt32Memory0() {
176:     if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
                                                                                   ^
177:         cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
178:     }
typescript/deps/ed25519xp/ed25519xp.js
memory is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
175: function getInt32Memory0() {
176:     if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
177:         cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
                                                        ^
178:     }
179:     return cachegetInt32Memory0;
typescript/deps/ed25519xp/ed25519xp.js
memory is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
175: function getInt32Memory0() {
176:     if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
177:         cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
                                                        ^
178:     }
179:     return cachegetInt32Memory0;
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_malloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
187: export const __wbg_stack_558ba5917b466edd = function(arg0, arg1) {
188:     var ret = getObject(arg1).stack;
189:     var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
                                                ^
190:     var len0 = WASM_VECTOR_LEN;
191:     getInt32Memory0()[arg0 / 4 + 1] = len0;
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_realloc is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
187: export const __wbg_stack_558ba5917b466edd = function(arg0, arg1) {
188:     var ret = getObject(arg1).stack;
189:     var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
                                                                        ^
190:     var len0 = WASM_VECTOR_LEN;
191:     getInt32Memory0()[arg0 / 4 + 1] = len0;
typescript/deps/ed25519xp/ed25519xp.js
__wbindgen_free is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
197:         console.error(getStringFromWasm0(arg0, arg1));
198:     } finally {
199:         wasm.__wbindgen_free(arg0, arg1);
                  ^
200:     }
201: };
typescript/deps/ed25519xp/ed25519xp.js
memory is not exported by typescript/deps/ed25519xp/ed25519xp_bg.wasm
220: 
221: export const __wbindgen_memory = function() {
222:     var ret = wasm.memory;
                        ^
223:     return addHeapObject(ret);
224: };
(!) Broken sourcemap
https://rollupjs.org/guide/en/#warning-sourcemap-is-likely-to-be-incorrect
Plugins that transform code (such as 'wasm') should generate accompanying sourcemaps

Though, upon evaluating the .wasm file as WAT, the exports seem to be present:

...
  (func $seed_from_phrase (export "seed_from_phrase") (type $t6) (param $p0 i32) (param $p1 i32) (result i32)
...
  (func $gen_keypair (export "gen_keypair") (type $t6) (param $p0 i32) (param $p1 i32) (result i32)
...
  (func $__wbindgen_malloc (export "__wbindgen_malloc") (type $t3) (param $p0 i32) (result i32)
...
  (func $__wbindgen_realloc (export "__wbindgen_realloc") (type $t8) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32)
...
  (memory $memory (export "memory") 18)
...

(I've uploaded the whole repo at https://github.com/nmrshll/ed25519/tree/943fc841693401acc64260fc19d4dda08ae3503d)

How can I fix the "Missing exports" bundling error ?

Nicolas Marshall
  • 4,186
  • 9
  • 36
  • 54
  • Did you find a solution to this problem? I'm experiencing it as well. – Duane J Oct 18 '20 at 03:26
  • My "solution" was to switch to webpack which seems to have better support for this. Not really a solution to this actual question though. Do you have the freedom to make the switch or are you stuck with rollup ? – Nicolas Marshall Oct 20 '20 at 14:26
  • I'm actually using snowpack, which uses rollup under the hood. I've opened a ticket here: https://github.com/rollup/plugins/issues/617 – Duane J Oct 23 '20 at 13:22

2 Answers2

3

Call wasm-pack with --target web instead.

Docs: https://rustwasm.github.io/docs/wasm-pack/commands/build.html#target

That's what removed those errors for me with a similar configuration. Although, I was using wasm-bindgen instead of wasm-pack.

lurvey
  • 167
  • 7
  • 2
    I had tried that: https://stackoverflow.com/questions/60452332/rollup-bundling-embedding-wasm-code-from-an-external-module It does make the bundler errors go away, but the embedded wasm code also goes away. I suppose it has to do with either my bundler config or the way I `import()` the wasm deps in my typescript code. I didn't find an answer yet for this problem with rollup, but using webpack instead (as suggested in the wasm-pack book / docs) got it to work. – Nicolas Marshall Mar 06 '20 at 18:15
2

Its a little bit late, but i had the same problem using rollup with an already compiled wasm-pack node module. (In my case i had the main svelte page using the wasm, and i wanted to use the same wasm file in a service worker aswell).

I quickly wrote a rollup plugin (poc) which allowes you to use a wasm-pack node module and will copy the required wasm file to your output directory.

As mentioned in the last answer, the wasm-pack module need to be built with "--target web".

If you want to compile directly your rust code i recommend using the rust plugin for rollup.

You can find rollup-wasm-pack-import here.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Priemar
  • 96
  • 5