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

How to bundle zbar.wasm in a module project? #11

Closed
iBobik opened this issue Aug 12, 2023 · 6 comments
Closed

How to bundle zbar.wasm in a module project? #11

iBobik opened this issue Aug 12, 2023 · 6 comments

Comments

@iBobik
Copy link

iBobik commented Aug 12, 2023

I develop capacitor-community/barcode-scanner and want to make it support off-line, so zbar.wasm needs to be included.

I successfully included it in a dist of this module:

  plugins: [
    copy({
      targets: [
        { src: 'node_modules/@undecaf/zbar-wasm/dist/zbar.wasm', dest: 'dist' },
      ]
    })
  ],

But when I use barcode-scanner in my project (npm i "@capacitor-community/barcode-scanner@../barcode-scanner" for local development) and build it, resulting dist does not include zbar.wasm file.

I checked example-bundled, but this seems not intended for use in the module project (and also it is for old rollup 2).

Or it is really necessary to ask module's users to bundle zbar.wasm themself? How to make zbar-wasm to require it correctly then?

Thank you for your help.

@undecaf
Copy link
Owner

undecaf commented Aug 18, 2023

@iBobik Apologies for my late reply, I have been on vacation. I cannot provide a simple solution to this issue; I can only present my findings, hoping that they are helpful.

CommonJS targets

The CommonJS build of @undecaf/zbar-wasm (i.e. the WASM/CommonJS glue logic generated by Emscripten) does not allow to detect any dependency on zbar.wasm (that filename is just an innocuous string literal), so IMHO all CommonJS projects will have to use a copy plugin for zbar.wasm. Nevertheless, I hope someone can prove me wrong.

Rollup 3

I have not been able to make Rollup bundle zbar.wasm automatically, no matter which target environment. @rollup/plugin-wasm did not help either.

Webpack 5

The WASM/ESM glue logic in @undecaf/zbar-wasm contains the instruction new URL('zbar.wasm', import.meta.url) which makes Webpack bundle zbar.wasm as an URL asset whenever it includes the ESM build of @undecaf/zbar-wasm.
Unfortunately, making Webpack select the ESM build presently requires an resolve.alias entry which is only a small improvement over a copy plugin. See this gist for example Webpack configurations.

Next steps for zbar-wasm

The export conditions in package.json of @undecaf/zbar-wasm 0.9.16 are quite a mess, so I understand that Webpack has to be forced to select the ESM build of zbar-wasm over the CommonJS build.
But even after setting the export conditions as documented for Webpack, I was not able to make Webpack select the ESM build of @undecaf/zbar-wasm when appropriate.
As I am not too familiar with Webpack, any hints would be welcome.

@fspoettel
Copy link

I don't know if this is helpful for this specific issue, I apologize if it is not. As vite uses rollup under the hood, I figured I post a working config for it:

import { defineConfig } from "vite";
import wasm from "vite-plugin-wasm";

export default defineConfig({
  plugins: [wasm()],
  // config below makes the build work.
  optimizeDeps: {
    exclude: [
      "@undecaf/zbar-wasm"
    ]
  },
});

this works both in dev and prod, where the build puts out wasm and properly externalizes module.

vite v4.4.8 building for production...
[plugin:vite:resolve] Module "module" has been externalized for browser compatibility, imported by "<snip>/node_modules/@undecaf/zbar-wasm/dist/main.js". See http://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
✓ 1302 modules transformed.
dist/index.html                                    0.49 kB │ gzip:  0.32 kB
dist/assets/index-d465abb6.js                     17.22 kB
dist/assets/zbar-d779f39f.wasm                   239.02 kB
dist/assets/index-b4c9e5df.css                    11.99 kB │ gzip:  3.02 kB
dist/assets/__vite-browser-external-b25bb000.js    0.03 kB │ gzip:  0.05 kB
dist/assets/index-dbe8b31c.js                    186.93 kB │ gzip: 61.10 kB
✓ built in 1.32s

@undecaf
Copy link
Owner

undecaf commented Aug 23, 2023

Thank you @fspoettel !

@iBobik Plugin @web/rollup-plugin-import-meta-assets can include zbar.wasm as an asset in Rollup 3. The module referencing @undecaf/zbar-wasm must be an ES module, and the plugin needs option warnOnError: true to be set. I provided a pull request so that this option is no longer needed.

Edit:

The latest version of @web/rollup-plugin-import-meta-assets (2.0.2) includes the pull request and no longer needs option warnOnError: true to be set.

undecaf added a commit that referenced this issue Sep 3, 2023
Test various bundling configurations with
Webpack, Rollup and esbuild and test the
resulting bundles.
@undecaf
Copy link
Owner

undecaf commented Sep 3, 2023

@iBobik zbar-wasm v0.10.0 should resolve this issue.

PTAL at tests/rollup.config.js which demonstrates several ways of bundling zbar-wasm with Rollup; I hope that one of them is suitable for your situation.

Closing this, please feel free to re-open.

@undecaf undecaf closed this as completed Sep 3, 2023
@iBobik
Copy link
Author

iBobik commented Sep 3, 2023 via email

@iBobik
Copy link
Author

iBobik commented Sep 20, 2023

@undecaf I am looking into it, but found I will probably need you to update also barcode-detector-polyfill.

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

3 participants