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

Error when bundling with webpack #2

Open
ostryhub opened this issue Apr 12, 2024 · 5 comments
Open

Error when bundling with webpack #2

ostryhub opened this issue Apr 12, 2024 · 5 comments
Assignees

Comments

@ostryhub
Copy link

ostryhub commented Apr 12, 2024

Hi, great wrapper around PlaneGCS, something I was looking for a long time, thank you for putting this project together!

I am trying to use this npm module in my js lib I am packing with webpack as UMD module.
When I try to build with this this package installed and imported I do get an error about module resolution.

In particular it complains that:

ERROR in ./node_modules/@salusoft89/planegcs/dist/planegcs_dist/planegcs.js 9:174-203
Module not found: Error: Can't resolve './' in '/Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/dist/planegcs_dist'
resolve './' in '/Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/dist/planegcs_dist'
  Parsed request is a directory
  using description file: /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/package.json (relative path: ./dist/planegcs_dist)
    using description file: /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/package.json (relative path: ./dist/planegcs_dist)
      as directory
        existing directory /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/dist/planegcs_dist
          using description file: /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/package.json (relative path: ./dist/planegcs_dist)
            using path: /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/dist/planegcs_dist/index
              using description file: /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/package.json (relative path: ./dist/planegcs_dist/index)
                no extension
                  /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/dist/planegcs_dist/index doesn't exist
                .tsx
                  /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/dist/planegcs_dist/index.tsx doesn't exist
                .ts
                  /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/dist/planegcs_dist/index.ts doesn't exist
                .js
                  /Users/rafal/Projects/LTBL/planegcs-js/node_modules/@salusoft89/planegcs/dist/planegcs_dist/index.js doesn't exist
 @ ./node_modules/@salusoft89/planegcs/dist/index.js 14:0-63 15:0-32 20:29-49
 @ ./src/index.ts 37:0-72 43:45-65 47:38-48

ERROR in /Users/rafal/Projects/LTBL/planegcs-js/src/index.ts
1:49-71
[tsl] ERROR in /Users/rafal/Projects/LTBL/planegcs-js/src/index.ts(1,50)
      TS2792: Cannot find module '@salusoft89/planegcs'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
ts-loader-default_e3b0c44298fc1c14

Does it have to do with how target javascript version emscripten is confoigured for ES5/ES6 and new js modules vs commonJS ?
Any pointers on why this happens and potentially how to solve would be greatly appreciated!

the test project attached as zip
planegcs-js.zip

@thes01
Copy link
Collaborator

thes01 commented Apr 12, 2024

Hi, glad to hear it's useful :)

Thank you for attaching the project. I'm not an expert in how different modules are resolved in different bundlers (it's a mess), but I'll give it a look.

@thes01 thes01 self-assigned this Apr 12, 2024
@thes01
Copy link
Collaborator

thes01 commented Apr 12, 2024

@ostryhub It seems the source of the issue is that Javascript "glue" code generated by Emscripten messes up with Webpack mechanisms, see webpack/webpack#7352.

I've tried building the library with -s ENVIRONMENT=web, which fixed the issue.
(also it was necessary to add "moduleResolution": "Node" to the compilerOptions in your project's tsconfig.json)

The problem is that I cannot use this build config since that would break node compatibility (which at least the library tests require). I suggest either changing your bundler to e.g. Vite, or try some of the suggestions in the mentioned issue. Alternatively, you may create a separate fork of this library with the altered build config, the change is in planegcs/CMakeLists.txt, line 51:
set_target_properties(planegcs PROPERTIES LINK_FLAGS "${BUILD_TYPE_FLAGS} -lembind --closure 1 -s EXPORT_ES6=1 -s MODULARIZE=1 -s MALLOC=emmalloc -s NO_FILESYSTEM=1 -s STACK_SIZE=5MB -s ENVIRONMENT=web")

I might also investigate if there is a way to include multiple different wasm builds into the library. That could also fix your problem.

@ostryhub
Copy link
Author

ostryhub commented Apr 12, 2024

@thes01 Thank you for such a quick answer and looking into the problem.
The idea of building web targeting emsc build does sound like a way to go for me.
I will give it a try after the weekend and share the results here.

Regarding the multi wasm build, I am unabe to help unfortunately, but maybe checking this great occt wasm port https://github.com/donalffons/opencascade.js/ could shed some more light on the possible configuration.

@thes01
Copy link
Collaborator

thes01 commented Apr 13, 2024

Yes, no problem :).

In OpenCascade.js, it seems that they ship just one build with the possibility of customization. (But anyway, there is a pretty nice process of the build configuration, which I might apply to planegcs as well)

I think it could be possible to just include multiple .wasm builds in the library (at least one for the browser-only). And then by using the locateFile argument, you could choose, which wasm variant to load.
const mod = await init_planegcs_module({ locateFile: () => wasm_url });

@ostryhub
Copy link
Author

ostryhub commented Jun 13, 2024

The web build did work when packaged into UMD module with webpack.
The CMakeLists.txt change I used in the end is this:

set_target_properties(planegcs PROPERTIES LINK_FLAGS "${BUILD_TYPE_FLAGS} -lembind --closure 1 -s SINGLE_FILE=1 -s EXPORT_ES6=1 -s USE_ES6_IMPORT_META=0 -s MODULARIZE=1 -s MALLOC=emmalloc -s NO_FILESYSTEM=1 -s STACK_SIZE=5MB -s ENVIRONMENT=web")

I am loading this UMD module into a vanialla v8 JS runtime and what also helped me a lot is this single file option that emdeds the wasm file as base64 encoded string into the js module loading file

-s SINGLE_FILE=1

Vanilla v8 doesn't have Base64 atob decoder needed for embedded wasm loading, so one last thing one needs is to include the Base64 js library and expose it as global atob variable, like so:

import {encode, decode} from "base-64"
const globalScope: any = window || process || global;
globalScope.atob = decode;
globalScope.btoa = encode;

Thank you @thes01 for the help and this wrapper again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants