title: How load an emscripten generated module in Vue.js in order to use its functions?
body: <p>As you can read here: <a href="https://forum.vuejs.org/t/wasm-how-to-correctly-call-a-webassembly-method-in-vue-js/83422/24" rel="nofollow noreferrer">https://forum.vuejs.org/t/wasm-how-to-correctly-call-a-webassembly-method-in-vue-js/83422/24</a> I'm trying to figure out how to import a module generated by emscripten in Vue.js in order to call its methods.</p>
  
  <p>Following the indications found here: <a href="https://stackoverflow.com/questions/53309095/how-load-an-emscripten-generated-module-with-es6-import">How load an emscripten generated module with es6 import?</a>  I compiled add.c with this command:</p>
  
  <pre><code>emcc add.c -o js_plumbing.js -s EXPORTED_FUNCTIONS="['_Add']" -s  
  EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap'] -s EXPORT_ES6=1 -s 
  MODULARIZE=1
  </code></pre>
  
  <p>and modified Result.vue accordingly in this way:</p>
  
  <pre><code>&lt;template&gt;
    &lt;div&gt;
      &lt;p button @click="callAdd"&gt;Add!&lt;/p&gt;
      &lt;p&gt;Result: {{ result }}&lt;/p&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
      import Module  from './js_plumbing'
      const mymod = Module();
      export default {
        data () {
          return {
            result: null
          }
        },
        methods: {
          callAdd() {
            const result = mymod.cwrap('Add',
              'number',
              ['number', 'number'],
              [1, 2]);
            this.result = result;
          }
        }
      }
  &lt;/script&gt;
  </code></pre>
  
  <p>But I got this error:</p>
  
  <pre><code>Failed to compile.
  
  ./src/components/js_plumbing.js
  Module build failed (from ./node_modules/babel-loader/lib/index.js):
  SyntaxError: Unexpected token, expected ( (3:25)
  
    1 | 
    2 | var Module = (function() {
  &gt; 3 |   var _scriptDir = import.meta.url;
      |                          ^
    4 |   
    5 |   return (
    6 | function(Module) {
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/l5iB8.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/l5iB8.jpg" alt="enter image description here"></a></p>
  
  <p>The only way I found to import emscripten generated Module and use its functions, is to use a sort of an "hack": manually adding 'export' keyword in the Module definition in js_plumbing_js, the javascript file generated by compiling add.c with: </p>
  
  <pre><code>emcc add.c -o js_plumbing.js -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap'] -s 
  ENVIRONMENT='web','worker'
  </code></pre>
  
  <p>Result.vue :   </p>
  
  <pre><code>&lt;template&gt;
    &lt;div&gt;
      &lt;p button @click="callAdd"&gt;Add!&lt;/p&gt;
      &lt;p&gt;Result: {{ result }}&lt;/p&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
      import * as js_plumbing from './js_plumbing'
      import Module  from './js_plumbing'
      export default {
        data () {
          return {
            result: null
          }
        },
        methods: {
          callAdd () {
            const result = js_plumbing.Module.ccall('Add',
              'number',
              ['number', 'number'],
              [1, 2]);
            this.result = result;
          }
        }
      }
  &lt;/script&gt;
  </code></pre>
  
  <p>js_plumbing.js  :  </p>
  
  <pre><code>// Copyright 2010 The Emscripten Authors.  All rights reserved.
  // Emscripten is available under two separate licenses, the MIT license and the
  // University of Illinois/NCSA Open Source License.  Both these licenses can be
  // found in the LICENSE file.
  
  // The Module object: Our interface to the outside world. We import
  // and export values on it. There are various ways Module can be used:
  // 1. Not defined. We create it here
  // 2. A function parameter, function(Module) { ..generated code.. }
  // 3. pre-run appended it, var Module = {}; ..generated code..
  // 4. External script tag defines var Module.
  // We need to check if Module already exists (e.g. case 3 above).
  // Substitution will be replaced with actual code on later stage of the build,
  // this way Closure Compiler will not mangle it (e.g. case 4. above).
  // Note that if you want to run closure, and also to use Module
  // after the generated code, you will need to define   var Module = {};
  // before the code. Then that object will be used in the code, and you
  // can continue to use Module afterwards as well.
  export var Module = typeof Module !== 'undefined' ? Module : {};
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/gevKh.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/gevKh.jpg" alt="enter image description here"></a></p>
  
  <p>But, as I said, I do not like this manual hack.
  Any suggestions on how to make the Module exportable, thus importable, without manually adding ‘export’ in js_plumbing.js file?</p>
  
  <p>1° Update)</p>
  
  <p>Following the indications of the answer here: <a href="https://stackoverflow.com/questions/59500326/how-to-call-a-webassembly-method-in-vue-js">How to call a webassembly method in vue.js?</a></p>
  
  <p>I compiled the add.c file in this way:</p>
  
  <pre><code>emcc add.c -o js_plumbing.js -s MODULARIZE=1
  </code></pre>
  
  <p>and then modified Result.vue as follows:</p>
  
  <pre><code>&lt;template&gt;
    &lt;div&gt;
      &lt;p button @click="callAdd"&gt;Add!&lt;/p&gt;
      &lt;p&gt;Result: {{ result }}&lt;/p&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
      import Module from './js_plumbing'
      export default {
        data () {
          return {
            result: null
          }
        },
        methods: {
          callAdd() {
            const instance = Module({
              onRuntimeInitialized() {
                console.log(instance._Add(1,2));
                this.result = instance._Add(1,2);
              }
            })
          }
        }
      }
  &lt;/script&gt;
  </code></pre>
  
  <p>There must be something I'm doing wrong, since I do get the console.log when clicking to the Add! button,but the output is not transferred to the  the html part of Result.vue:
  <a href="https://i.stack.imgur.com/zFQBh.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zFQBh.jpg" alt="enter image description here"></a></p>