mediapipe: `@mediapipe/selfie_segmentation` npm package can be bundled by Rollup, but raises an error in runtime.

First of all, thank you for publishing this great library. I’m new to this library and TypeScript, so not sure that this is actually a bug. Please let me know if you have any misunderstandings 🙏

System information (Please provide as much relevant information as possible)

Describe the current behavior:

Failed to instantiate the SelfieSegmentation class from a JavaScript file bundled by Rollup.

The screenshot below shows the error message (please refer to the following Standalone code to reproduce the issue section about what is the context of index.html): screenshot0

Describe the expected behavior:

Be able to instantiate SelfieSegmentatoin class without errors (the Hello World! message below is emitted after the instantiation). screenshot1

Standalone code to reproduce the issue:

I created a small example package, that provides a class only instantiating SelfieSegmentation, to reproduce this issue.

// Files.
$ ls
index.html index.ts package.json rollup.config.js

// Build this package.
$ npm install
$ npm run build

// Open `index.html` on a browser (Chrome in my case).
// The result has been shown at the first screenshot.
$ open index.html

index.html:

<html>
  <head>
    <meta charset="utf-8">
    <title>Example</title>
  </head>
  <body>
    <script src="bundle.js"></script>
    <script>
      const selfie = new window.Example.SelfieSegmentationWrapper();
      console.log("Hello World!");
    </script>
  </body>
</html>

index.ts:

import {SelfieSegmentation} from "@mediapipe/selfie_segmentation";

class SelfieSegmentationWrapper {
    private inner: SelfieSegmentation;

    constructor() {
        this.inner = new SelfieSegmentation({
            locateFile: (file: string) => {
                return `"https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}`;
            },
        });
        this.inner.setOptions({
            modelSelection: 1,
        });
    }
}

export { SelfieSegmentationWrapper };

package.json:

{
  "name": "example",
  "version": "0.0.0",
  "scripts": {
    "build": "rollup -c ./rollup.config.js"
  },
  "devDependencies": {
    "@rollup/plugin-commonjs": "^21.0.1",
    "@rollup/plugin-node-resolve": "^13.0.6",
    "@rollup/plugin-typescript": "^8.3.0",
    "rollup": "^2.61.1",
    "typescript": "^4.5.3"
  },
  "dependencies": {
    "@mediapipe/selfie_segmentation": "^0.1.1632777926"
  }
}

rollup.config.js:

import typescript from '@rollup/plugin-typescript';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';

export default {
    input: 'index.ts',
    plugins: [
        typescript(),
        commonjs(),
        resolve()
    ],
    output: {
        sourcemap: false,
        file: 'bundle.js',
        format: 'umd',
        name: 'Example',
    }
};

Other info / Complete Logs :

I don’t exactly know why it works but if the line exports.SelfieSegmentation = SelfieSegmentation; is appended to selfie_segmentation.js, the problem is disappeared:

$ echo 'exports.SelfieSegmentation = SelfieSegmentation;' >> node_modules/@mediapipe/selfie_segmentation/selfie_segmentation.js
$ npm run build

// Now, the "Hello World!" message is printed as shown in the second screenshot.
$ open index.html

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 5
  • Comments: 15

Commits related to this issue

Most upvoted comments

Just FYI, I implemented a custom rollup plugin that appends the line exports.SelfieSegmentation = SelfieSegmentation; to the selfie_segmentation.js during the bundle phase as our workaround: https://github.com/shiguredo/media-processors/blob/develop/packages/virtual-background/rollup.config.js#L73

Thanks for sharing. In my case the error was related to MediaPipe Facemesh, so I adjusted the plugin as follows:

function mediapipe_workaround() {
  return {
    name: "mediapipe_workaround",
    load(id) {
      if (path.basename(id) === "face_mesh.js") {
        let code = fs.readFileSync(id, "utf-8")
        code += "exports.FaceMesh = FaceMesh;"
        return { code }
      } else {
        return null
      }
    },
  }
}

Just FYI, I implemented a custom rollup plugin that appends the line exports.SelfieSegmentation = SelfieSegmentation; to the selfie_segmentation.js during the bundle phase as our workaround: https://github.com/shiguredo/media-processors/blob/develop/packages/virtual-background/rollup.config.js#L73

Awesome, thanks so much. This works for me!

I use this plugin now in my vite.config.ts under build.rollupOptions.plugins.

Just FYI, I implemented a custom rollup plugin that appends the line exports.SelfieSegmentation = SelfieSegmentation; to the selfie_segmentation.js during the bundle phase as our workaround: https://github.com/shiguredo/media-processors/blob/develop/packages/virtual-background/rollup.config.js#L73

@Bersaelor That mediapipe_workaround method in the quoted message is the full plugin, you call it within vite’s build.rollupOptions.plugins.

For posterity, here’s a permalink to the original by @sile that I based it on (it looks like they just renamed the file extension which broke that other link). And here’s where it’s used in the config.

@kuaashish I see. It’s okay to close this issue 👍

This might help to understand the issue:

Rollup CommonJS plugin can’t work with obfuscated packages because it relies on static analysis to determine its exports.