emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.73k stars 3.3k forks source link

Tutorial is confusing; error handling could be better #14265

Open allan-bonadio opened 3 years ago

allan-bonadio commented 3 years ago

Thanks for emscripten, I've finally achieved liftoff, and working on my project. My letter today is fairly long, but has a lot of constructive suggestions, for the tutorial and the code, from a new-user perspective. Read it carefully! Because I want enscriptem to succeed, and the more people who can use it, the better. I'm a programmer who does a lot of ui/ux and tech writing.

One thing that took me a few hours time was that your tutorial was so confusing. It's not like you don't have enough documentation - it's more like there's too much. Too much, at least, for a tutorial. Every step of the way, there's three or four ways to do everything. I pick one way, but something doesn't work cuz method C, above, doesn't work with method 2, below, and I have to keep reading stuff to figure out why.

A tutorial should make someone successful, ASAP, without fail. No decisions, step 1 2 3, and it works the first time. The details can come later, after I have something working. All the stuff you've written is good, but it's all reference material, not tutorial. I'm a new user; I want to try it in isolation before I smoosh it into my larger app. Take the Download & Install page https://emscripten.org/docs/getting_started/downloads.html . The first thing, it tells you about two other ways to do it besides what's on the page.

Why would I care for either of these? I'm in foreign territory, I have no idea what to do, why would I take unnecessary chances? I can do that later, after I've learned to doggy paddle.

400 words into the Emscripten Tutorial, you finally get down to business: a Hello World program. We don't need to dig up the file you've hidden in your directory jungle. And we don't need a copyright - YOU don't need a copyright that takes up 77% of the file. It's 4 friggin lines, and every C programmer has memorized it:

#include <stdio.h>
int main() {
  printf("hello, world!\n");
}

I'd be happy to type it in by hand (as a tutorial reader), but copying from your web page and pasting it into a file is easier.

In the 'Generating HTML' section, you give us a command to make an html file. Then, you turn around and tell us that it won't work. (After I've already tried and it didn't work. And I said to myself, emscripten's so difficult!) Make some way for the Hello World tutorial to work immediately, in one step, including file: protocol.

After failing that, you tell me to compile this SDL program. I don't even know what SDL is, and why should I care. I've already done SVG and WebGL. Yawn. I guess some other people would like it. More reference material.

Far more useful would be if I could get hello_world.c to work in my React app. It's so simple! should be easy. I try copying the <script line from hello.html into React's index.html file - the outside html file. This line:

Thats all I need, right? (yeah it is, but I was tempted to copy out the 3.6k of JS code just above it... PS: you can get rid of the type= attribute, that's the default, it'll work fine.) I paste it into React's index.html file, but I get these errors:

CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f

actually, 3 or 4 copies of the same message, but whatever. Why is it doing this at Javascript Compile time? (really it was at wasm compile time - update your message to be more specific that its wasm compile time, because React COMPILES JSX to JS - long story. Coffeescript COMPILES to JS. Typescript COMPILES to JS.) I recognized 00 61 73 6d as the start of the wasm file. (actually what happened: no hello.wasm file, so I get an HTML error msg file that starts with <!DOCUMENT... ) The rest of the Tutorial page is useless, especially the Optimization section - I won't need that for months, maybe next year.

So then I push aside React's index.html file and just rename hello.html to index.html (the React server is very fussy - not general purpose... gee is that the problem!??! turns out, no, but that wastes more time.) React flips out and spews error messages, but I ignore them; it's ok. I'm still getting the 'magic word' error messages - exact same hex numbers, every time. No hello world yet. Why is it so hard?

Somewhere in your docs, I read that you need BOTH the .js and the .wasm file TOGETHER. (Can't find it now - I have 8 pages in Chrome open to your site. You have lots of wonderful Reference documentation.) So, I copy a.out.wasm right up next to index.html (which is really hello.html). But I still get the 'magic word' error message.

Also this message: wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm' .
Another clue, but still cryptic.

Hmmmm... so I'm crawling around in the debugger. I keep on seeing this URL, "http://localhost:3000/hello.wasm" . But that's wrong, it should be hello.js or hello.html, or else a.out.wasm . All three files were there, ready for reading. Then I got a clue: I renamed the .wasm file to hello.wasm . Then it worked!

Nowhere in your tutorial did it tell me to do that, I had to pound through and figure it out by myself. (or maybe it did say, on page 4172... but I didn't stumble onto it.) If I hadn't been good at the debugger, you might have lost a customer. You probably are losing customers. Your tutorial has to be falling-off-the-barstool simple. But I'll tell ya, once I saw that Hello World come out of the browser console, I knew I'd arrived. Everything else was going to be easy.

Javascript and C, calling each other, in the browser!! It was like crawling into a cave, and you come out the other side, and you're in Denmark! Amazing! And you know you can go back into the cave and come back home, easy. And you can go to other places, if you just read the documentation and play with it a bit. The hard part is over.

Here was some other people who ran into the 'magic word' problem. Note that the hex numbers are exactly the same as mine. Seeing that a lot of emscripten users keep on having the same problem, and the WebAssembly people don't want to deal with it, you should do something about it. If you detect that you're getting a <!DOCUMENT text, you can insert it into the DOM so the user can see it as part of an error message (the html data does have an error message in it i think).

CompileError: AsyncCompile: Wasm decoding failed: expected magic word 00 61 73 6d, found 3c 21 44 4f @+0

CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0

CompileError: AsyncCompile: Wasm decoding failed: expected magic word 00 61 73 6d, found 3c 21 44 4f @+0

Try these to ram the error page in front of the user's face:

document.body.append(goofyHTMLDataString);
document.body.prepend(goofyHTMLDataString);

You should have a streamlined tutorial, emphasizing immediate success for the new programmer who just downloaded your stuff, and doesn't know anything. Then, your existing docs are great as, like, a detailed tour, for those who already know the basics, and want to know, here and there, all the alternatives they can try. So many alternatives, it's great, I know I can surmount any challenge with emscripten!

sbc100 commented 3 years ago

Thanks @allan-bonadio for your feedback! We could love to improve the tutorial and I think some of your advise is really good. I especially like the idea of focusing on the one way to do things, at least initially.

Regarding using React in the initial tutorial, I would consider integrating with React as very advnaced thing to try to do. I think the basic tutorial is right to simply use the emscripten-generated hello.html along with a suitable webserver (emrun for example). Integration with other frameworks such as react (which I for one have no idea about) seem like advanced topics to me.

Regarding all those CompileError message.. those are exceptions that messages thrown from the browser itself, they are not coming from emscripten. Perhaps there is some way to can catch them before they happen in debug build. I'm kind of curious how you ended up seeing that message or why you think it will be common thing for folks to see.. it seems that html.html and hello.wasm would need to confused somehow so that emscripten tries to compile the html as a wasm file.. how/why would that happen and why would it be common? Perhaps its related to your react integration somehow?

Regarding a.out.wasm.. that file will only be generated alongside a.out.js and a.out.html when no output names is given. If you give your output a name -o hello.html for example then all three files will be called hello. I'm not sure how you ended up with mixed names but emscripten will always generate all 3 of those files with the same base name.

Regarding generated html. I'm not sure what you mean by "Then, you turn around and tell us that it won't work.".. it does work, we just note that you need a serverserver to host it because webassembly does run over the file:// protocol. It should just work unmodified using any server such as python -m SimpleHTTPServer or ./emrun which comes with emscripten. Maybe we can make this more clear and less negative sounding?