rustwasm / wasm-pack

📦✨ your favorite rust -> wasm workflow tool!
https://rustwasm.github.io/wasm-pack/
Apache License 2.0
6.2k stars 404 forks source link

docs: add documentation for working with wasm-pack outside of template #533

Open lrlna opened 5 years ago

lrlna commented 5 years ago

💡 Feature description

Although the template is a helpful resource to get started with wasm-pack, I find that documentation for working with it in more complex situation is lacking.

I am hoping that people who are also working outside of the provided template might jump in with some of the things they've had to tweak, so we can gather a wider range of use cases \o/

I've gathered a few things that I've ran into. Hopefully at least some of this information is useful for putting together more extensive documentation.

Importing async

To be able to add .wasm to the project, it needs to be imported async. Templates use a wrapper file to wrap the entire application in an async import. Subsequently, you can do a standard import of your webpack module. @ashleygwilliams helped me out figuring this out with a drawing, I made v2.0 of the said drawing: module-loading

This approach works if you are able to change the way your application builds. For those who are not able to change to their build, I solved the problem with just a dynamic import of the my module:

  1. Dynamic import does not work everywhere (can i use), so one will very likely require a babel plugin to handle this. babel-plugin-syntax-dynamic-import is what i used:

      // in .babelrc
      {  
        "plugins": [
          "syntax-dynamic-import"
        ]
      }

    Otherwise you end up with this error:

    screen shot 2019-01-29 at 13 12 42
  2. Then inside the project something like this can be done:

      // initial import that will have to be used as a promise later on in code
      const schemaWasm = import('mongodb-schema-parser');
    
      function getSchema(doc) { 
        // .then on the previously imported module
        schemaWasm
          .then(module => {
            // use the module's API
            const schemaParser = new module.SchemaParser();
            schemaParser.write(doc)
            return schemaParser.toJson();
          })
          .catch(e => return new Error(`Error in mongodb-schema-parser ${e}`))
      }

Webpack configuration

Depending on people's webpack version and build target a few options are possible:

ashleygwilliams commented 5 years ago

@lrlna would you be interested in adding some of this documentation? I'd welcome PRs and would be happy to help you get started if you'd like! Let me know!

lrlna commented 5 years ago

hey @ashleygwilliams yea I can add some of this in sometime in the next two weeks. If anyone has different experiences, we can always update I suppose! Where does the book's source live exactly? And what section would you like me to add this to?

MaxBittker commented 5 years ago

Thanks for writing such a detailed issue! I'm having the issue you describe can result from not having @babel/plugin-syntax-dynamic-import ... but i think I do have this plugin. It's possible I've just made other webpack errors, but posting this in case others are experiencing the problem

MaxBittker commented 5 years ago

oh... there's a bug in webpack 4.29.0 https://github.com/webpack/webpack/issues/8656

lrlna commented 5 years ago

@MaxBittker, yep there was a bug last week! Try and see if 4.29.6 works for you (it worked for me).

lirhtc commented 5 years ago

Hi @lrlna, thanks for the drawing. It makes the whole import process very clear. I am now trying to figure out how to import a wasm module in an Electron app and have no idea to do so. Is that possible to provide some more information about how to do it please?

lrlna commented 5 years ago

hey @lirhtc! if you have webpack > 4.16.0, you should be able to import as is wherever you need it. If you have babel running, I'd also add this babel-dynamic-import-plugin. I think the first two steps I've outlined in Importing Async + having webpack > 4.16.0 should work. Let me know if it doesn't! Happy to help brainstorm!

// import that works in my setup with electron 3.0.7 and webpack 4.29.6
var wasm = import('wasm')
function runWasmAction (param) { 
  // .then on the previously imported module
  wasm
    .then(module => {
      // use your module's API
    })
    .catch(e => return new Error(`Error in wasm module ${e}`))
}