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

Issue running test with Tensorflow.js #1876

Open
thekevinscott opened this issue Feb 10, 2022 · 7 comments
Open

Issue running test with Tensorflow.js #1876

thekevinscott opened this issue Feb 10, 2022 · 7 comments

Comments

@thekevinscott
Copy link

Hello there,

I'm trying to write a unit test on some code that leverages Tensorflow.js.

Here's a sample test:

import { expect } from '@esm-bundle/chai';
import * as tf from '@tensorflow/tfjs';
console.log(tf);
export const foo = (a:number, b:number) => a + b
it('foos', () => {
  expect(foo(1, 2)).to.eql(3);
})

This fails with the error:

 🚧 Browser logs:
      ReferenceError: module is not defined
        at ../../node_modules/long/src/long.js:1:1

 ❌ Could not import your test module. Check the browser logs or open the browser in debug mode for more information.

Chromium: |██████████████████████████████| 1/1 test files | 0 passed
, 0 failed

I've tried (via playwright) Firefox and Webkit, and get the same error.

Tensorflow.js specifies backends that can be CPU or WebGL. My best guess is this is where the problem lies.

If I open a Debug window in Chrome, I can inspect long.js. I'm not entirely sure where it's loaded from, but I assume TFJS; here's the beginning of that module:

module.exports = Long;

/**
 * wasm optimizations, to do native i64 multiplication and divide
 */
var wasm = null;

try {
  wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([
    0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11
  ])), {}).exports;
} catch (e) {
  // no wasm support :(
}

I tried setting the backend to leverage the CPU instead, but that doesn't seem to have an effect.

Do you have any feedback in how to interpret the error ReferenceError: module is not defined? I'm not exactly sure what this means.

Thanks!

@thekevinscott thekevinscott changed the title Issues running test with TFJS Issue running test with TFJS Feb 10, 2022
@thekevinscott thekevinscott changed the title Issue running test with TFJS Issue running test with Tensorflow.js Feb 10, 2022
@bennypowers
Copy link
Member

can you try applying the rollup commonjs plugin in your test runner config per https://modern-web.dev/guides/going-buildless/es-modules/#transform-commonjs-to-esm

@thekevinscott
Copy link
Author

Thank you for the advice! I'll try when I'm back in front of my computer.

@thekevinscott
Copy link
Author

thekevinscott commented Feb 13, 2022

Apologies for the delay @bennypowers.

Applying the rollup commons plugin didn't seem to help.

I created a minimal repo that reproduces the issue here:

https://github.com/thekevinscott/wtr-tfjs-test

It's got two tests, sum.test.js (which works) and getTensor.test.js (which does not). I also set up a Github CI run so you can see the test execution here:

https://github.com/thekevinscott/wtr-tfjs-test/runs/5174139315?check_suite_focus=true

Here's the output of that test run:

$ web-test-runner "src/**/*.test.js" --node-resolve

src/getTensor.test.js:

 🚧 Browser logs:
      ReferenceError: module is not defined
        at node_modules/long/src/long.js:1:1

   Could not import your test module. Check the browser logs or open the browser in debug mode for more information.

Chrome: |██████████████████████████████| 2/2 test files | 1 passed, 0 failed

Error while running tests.

error Command failed with exit code 1.

Here is my web-test-runner.config.js:

const rollupCommonjs = require('@rollup/plugin-commonjs');
const { fromRollup } = require('@web/dev-server-rollup');

const commonjs = fromRollup(rollupCommonjs);

module.exports = {
  files: ['**/*.test.ts'],
  plugins: [
    commonjs({
      include: [
        './node_modules/@tensorflow/**/*',
      ],
    }),
  ],
};

@bennypowers
Copy link
Member

wtr-tfjs-test/node_modules/@tensorflow/tfjs-core/node_modules/seedrandom/lib/alea.js is neither a javascript module nor a commonjs module, and it looks like commonjs plugin is having difficulty dealing with it.

I can't dig into it further right now but hopefully that clue is helpful. Have you considered bundling tf.js using esbuild prior to running the dev server, and redirecting imports to the bundled files?

@thekevinscott
Copy link
Author

I tried a few strategies with regards to esbuild.

1 - esbuild as a plugin. Didn't work.

2 - esbuild as a pre-bundling step. Also didn't work (though a different error this time).

3 - TFJS also publishes a pre-bundled file, tf-es2017.js. Tried that here, also didn't work. Same error as (2)

@bengfarrell
Copy link

Hi there, I'm using @web/dev-server on a TFJS based pose estimation component I'm dabbling with. It's nowhere near done, but I did have some pain getting it working using ESM. Right now, I can do pose/face/hand estimation which relies on the GPU TFJS implementation.

My strategy was pre-bundling, but I've used this strategy in the past on other similarly stubborn libraries and when I need the implementation to match I end up hand creating an adapter to make sure the ESM modules from my bundle match what you'd expect from the CJS based solution. I didn't do that here because I didn't care.

Anyway, maybe my repo would help? I have the Rollup bundling configs in my rollup.configs folder.
https://github.com/bengfarrell/pose-capture

Hope it helps! If not good luck!

@thekevinscott
Copy link
Author

Really appreciate that @bengfarrell ! I'll take a look and follow up with questions / what I find.

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