jsscheller / imagemagick-wasm

imagemagick compiled to WASM
Apache License 2.0
2 stars 2 forks source link

Using in browser with ESBuild #1

Open ben-katz opened 1 year ago

ben-katz commented 1 year ago

When I follow the example, I see this error:

Uncaught Error: Dynamic require of "https://unpkg.com/@jspawn/imagemagick-wasm/magick.mjs" is not supported

Instead, I tried importing like:

import createModule from '@jspawn/imagemagick-wasm/magick.mjs';

But then when building, I get this:

error esbuild error
    Build failed with 5 errors:
    node_modules/@jspawn/imagemagick-wasm/magick.js:11:17: ERROR: Could not resolve "path"
    node_modules/@jspawn/imagemagick-wasm/magick.js:11:77: ERROR: Could not resolve "fs"
    node_modules/@jspawn/imagemagick-wasm/magick.js:113:465: ERROR: Could not resolve "child_process"
    node_modules/@jspawn/imagemagick-wasm/magick.mjs:12:35: ERROR: Could not resolve "path"
    node_modules/@jspawn/imagemagick-wasm/magick.mjs:12:51: ERROR: Could not resolve "module"  
jsscheller commented 1 year ago

Uncaught Error: Dynamic require of "https://unpkg.com/@jspawn/imagemagick-wasm/magick.mjs" is not supported

error esbuild error
    Build failed with 5 errors:
    node_modules/@jspawn/imagemagick-wasm/magick.js:11:17: ERROR: Could not resolve "path"
    node_modules/@jspawn/imagemagick-wasm/magick.js:11:77: ERROR: Could not resolve "fs"
    node_modules/@jspawn/imagemagick-wasm/magick.js:113:465: ERROR: Could not resolve "child_process"
    node_modules/@jspawn/imagemagick-wasm/magick.mjs:12:35: ERROR: Could not resolve "path"
    node_modules/@jspawn/imagemagick-wasm/magick.mjs:12:51: ERROR: Could not resolve "module"  
ben-katz commented 1 year ago

Thanks @jsscheller!

I took a look through the esbuild issues etc. and am not entirely sure how to fix this. I might try making my own issue.

However, is it possible to compile without Node capabilities altogether? I am only using it in browser. Would this be something a beginner like myself could figure out?

jsscheller commented 1 year ago

To answer your question, you can prevent those Node.js imports by removing the two Node.js related flags in the build script:

However, it looks like ESBuild has the ability to ignore those imports: https://github.com/evanw/esbuild/issues/2852.

ben-katz commented 1 year ago

Thanks so much for the response. With the help of Yuan Qing I was able to stop those Node-only packages from being bundled, and I can build the app without error. But now, it seems like imagemagick-wasm isn't working...

Here is the relevant part of my UI code:

import createModule from '@jspawn/imagemagick-wasm/magick.mjs';

function Plugin() {

  async function runstuff() {
    // Returns an Emscripten "Module": https://emscripten.org/docs/api_reference/module.html
    // NOTE: only parts of the Module object are exposed due to minification - see `build.sh`.
    const magick = await createModule({
      // Tell Emscripten where the WASM file is located.
      locateFile: () => "https://unpkg.com/@jspawn/imagemagick-wasm/magick.wasm",
    });

    // Writes a blank image to `blank.png` (via Emscripten's in-memory filesystem).
    magick.callMain(["-size", "100x100", "xc:blue", "blue.png"]);

    // Read the file to a blob.
    const pngBuf = magick.FS.readFile("blue.png");
    const pngBlob = new Blob([pngBuf], { type: "image/png" });
  }

  useEffect(() => {

    runstuff()

  }, []);

  ...

and when I run the UI I get:

Uncaught (in promise) ReferenceError: createModule is not defined
    at <anonymous>:5143:44
    at async runstuff (<anonymous>:5165:22)

Is it perhaps something to do with async?

jsscheller commented 1 year ago

I don't see how that error could be possible. createModule is defined in the first line of your snippet. I would guess the code you are trying to run differs from the summary you provided in your snippet.

ben-katz commented 1 year ago

I've triple checked that I am running the right code. There might be something I did that is causing issues though. As I'm using typescript, when I first tried loading the module I got:

error TS7016: Could not find a declaration file for module '@jspawn/imagemagick-wasm/magick.mjs'. 'Z:/Development/Figma Plugins/Print for Figma React/wasm testing/wasm/node_modules/@jspawn/imagemagick-wasm/magick.mjs' implicitly has an 'any' type.
      Try `npm i --save-dev @types/jspawn__imagemagick-wasm` if it exists or add a new declaration (.d.ts) file containing `declare module '@jspawn/imagemagick-wasm/magick.mjs';`

    17 import createModule from '@jspawn/imagemagick-wasm/magick.mjs';

So, I did what it said and made a decs.d.ts file, and inside it I put: declare module '@jspawn/imagemagick-wasm/magick.mjs';

This made things build. I couldn't seem to find types for your module so I thought this would work, but maybe it is messing with the import somehow?

jsscheller commented 1 year ago

It would be useful if this module included a Typescript definition file. I will look into that.

Regarding the troubles you are having, I don't believe it is an issue with this module. The browser example was designed to work directly in the browser without any bundler: https://github.com/jsscheller/imagemagick-wasm/blob/master/examples/browser/index.html. If you have troubles with that, let me know, but I can't offer much assistance when it comes to issues with your particular setup.