Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bundler annotations to make o1js work in Angular #910

Closed
directcuteo opened this issue May 10, 2023 · 16 comments
Closed

Add bundler annotations to make o1js work in Angular #910

directcuteo opened this issue May 10, 2023 · 16 comments
Labels
ui Issues related to frontend / ui integration

Comments

@directcuteo
Copy link

I want to include the capabilities of SnarkyJS in my web application. The only code I added that uses snarkyjs is the following one.

import { SmartContract } from 'snarkyjs';

class Square extends SmartContract {
}

This resulted in the error below. The error is coming from a snarkyjs file.
Have I made a mistake?

image

image

@mitschabaude
Copy link
Contributor

can you add more context about your build setup / UI framework? it seems parts of snarkyjs that are necessary are not bundled properly

@directcuteo
Copy link
Author

I am using it in an Angular v15 app which is built using Webpack v5.75.0

@mitschabaude
Copy link
Contributor

@ymekuria do you have an idea what could happen here?

@directcuteo
Copy link
Author

@mitschabaude Do you have any updates regarding this issue? Thanks!

@mitschabaude
Copy link
Contributor

@directcuteo I haven't looked into it. It seems that Angular / webpack is trying to compile snarkyjs' web bundle and is doing something wrong. Since snarkyjs' bundle should work as is, without transpilation, maybe there's some option that you can give to webpack to ignore snarkyjs when bundling the code, i.e. leave it untouched?

@directcuteo
Copy link
Author

@mitschabaude can you share a simple HTML + Javascript example of how to use o1js?

I can't really figure out what is going on but Angular has a big community so maybe it should be included in the integration tutorial.
Thanks!

@mitschabaude
Copy link
Contributor

mitschabaude commented Sep 12, 2023

sure! plain html & js example:

  • take index.js which is shipped in the npm package at /dist/web/index.js
  • make sure index.js is located next to index.html
  • serve the following index.html:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>hello-snarkyjs</title>
    <script type="importmap">
      { "imports": { "snarkyjs": "./index.js" } }
    </script>    
    <script type="module">
      import { Field } from "snarkyjs";
      console.log(Field(-1));
    </script>
  </head>
  <body>
    <div>Check out the console (F12)</div>
  </body>
</html>

@mitschabaude
Copy link
Contributor

So the point is, it's better if your web framework doesn't try to transform the snarkyjs build output (bundling should be fine; it should know where to resolve it from the package.json "exports" field)

@directcuteo
Copy link
Author

Your example works, I appreciate!

My opinion:
The thing is that because I import SmartContract in an Angular component, Angular will include o1js in its bundling/tree-shaking thing. The problem is that this changes the names of functions and variables. By default this should not be an issue. The issue is that wasm is imported later and it will call a function from javascript which (and here is the surprise) doesn't exist anymore because of the tree-shaking.
Following this discussion evanw/esbuild#458 if I get it right, there should be some flag added in o1js that will not allow the tree-shaking because it has side-effects (wasm will fail to call the functions).
What are your thoughts?

@mitschabaude
Copy link
Contributor

@directcuteo wow, thanks for investigating! I'll look into this

@mitschabaude mitschabaude changed the title SnarkyJS integration error Add bundler annotations to make o1js work in Angular Sep 13, 2023
@mitschabaude mitschabaude added the ui Issues related to frontend / ui integration label Sep 13, 2023
@directcuteo
Copy link
Author

Small upd: building o1js locally and using it in the Angular app without the minifier resulted that the undefined function is _mainWorker

image

@mitschabaude
Copy link
Contributor

hm that's weird.. this is a transformed version of the code here, which has normal function code inside mainWorker():
https://github.com/o1-labs/o1js-bindings/blob/66061bfd2349c16414330410881fcf6e6473ed6d/js/web/web-backend.js#L117-L124

@mitschabaude
Copy link
Contributor

mitschabaude commented Sep 13, 2023

Maybe Angular does something clever with Worker calls that interferes with the very custom way we create web workers

@directcuteo
Copy link
Author

That transformed version is coming from a blob file imported via http request.

Screenshot 2023-09-13 at 16 40 08

I am wondering how does webpack/angular come in play here anyway. Do you know how that file is created?

@mitschabaude
Copy link
Contributor

Do you know how that file is created?

Yes it's created on the fly from function source code, with Function.toString(), which is then put in a Blob, which then the worker is created from
See explanation here: #33

@directcuteo
Copy link
Author

Do you know if this works with react? Isn't react also bundled by webpack?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ui Issues related to frontend / ui integration
Projects
None yet
Development

No branches or pull requests

3 participants