RobotWebTools / roslibjs

The Standard ROS JavaScript Library
https://robotwebtools.github.io/roslibjs
Other
694 stars 382 forks source link

Issue with roslibjs and Vite #548

Open kavidey opened 2 years ago

kavidey commented 2 years ago

I am using roslibjs with a project that uses Vite as the build system and am running into an issue when running the project in development.

Steps To Reproduce Minimum reproducible project here: https://github.com/kavidey/vite-sample-roslib Run npm run dev to get the error, or npm run build then npm run preview to see the project working properly.

Expected Behavior In both dev and preview mode, importing roslibjs should work without any errors.

Actual Behavior When running the code in dev mode, I get the error: ReferenceError: Can't find variable: Buffer.

That error traces back to core/Ros.js requiring ws. I think that the ws shim may not be working correctly when vite is running in dev mode and roslibjs thinks that its running in node so it tries to require ws, though I'm not sure.

MatthijsBurgh commented 2 years ago

I have really no clue. I also have to say this is a bit out of the support scope. I have to say I have never experienced any issue with webpack-dev-server.

When you are able to provide a solution that requires to be implemented in the library, I am open to that. But I am not able to help you finding that solution.

desstiony commented 2 years ago

Just replace import 'roslib/build/roslib' with import 'roslib/build/roslib'

MatthijsBurgh commented 2 years ago

@desstiony you suggest to replace it with the same....

desstiony commented 2 years ago

Sorry, I made a typo. you should replace "import * as ROSLIB from 'roslib'" with 'roslib/build/roslib' in main.js file.

MatthijsBurgh commented 2 years ago

So you mean replace import * as ROSLIB from 'roslib' with import * as ROSLIB from 'roslib/builld/roslib'?

desstiony commented 2 years ago

Just import 'roslib/build/roslib', you can try it.

MatthijsBurgh commented 2 years ago

I am not using Vite. It wasn't clear to me. So I thought it might not be clear to other people.

desstiony commented 2 years ago

I have tried it in the codespace of this repository hope it can help you. @kavidey

kavidey commented 2 years ago

Thank you @desstiony. This is a great fix for now!

Because we're importing the fully compiled browser version, it creates a global window.ROSLIB object instead of putting it into a local variable. This means we don't get tree shaking or quite as clean syntax (SSR also for those code segments also has to be disabled because that build of ROSLIB cannot run on the server)

I added a shim file to simplify the import syntax, so now it looks like import ROSLIB from './roslib.shim'; and we don't need to look at the global variable. Changing the file extension of the shim to .ts also gives typescript support.

I think if possible it would be great to try and find a solution that doesn't require using the precompiled version of roslib, but this works great for now!

Interpause commented 2 years ago

The issue with the import shim failing is likely due to https://github.com/vitejs/vite/issues/7576, which is waiting on PR https://github.com/vitejs/vite/pull/8709.

A workaround is possible by using Vite's resolve.alias to mimick the shims below:

https://github.com/RobotWebTools/roslibjs/blob/7aac4c5b752107f06546a4762827457d36b91028/package.json#L8-L14

In vite.config.js:

{
  // ...
  resolve: {
    alias: {
      './src/RosLibNode.js': './src/RosLib.js',
      canvas: './canvas',
      ws: '../util/shim/WebSocket',
      '@xmldom/xmldom': '../util/shim/@xmldom/xmldom',
      '../util/decompressPng': '../util/shim/decompressPng',
    }
  }
}

Note the above could have undesireable side effects if you so happen to also import those paths.

Alternatively, why not import the shims directly then use the below trick to either import the NodeJS dependencies or browser dependencies?

https://github.com/RobotWebTools/roslibjs/blob/7aac4c5b752107f06546a4762827457d36b91028/src/util/shim/WebSocket.js#L1

loran-luo commented 7 months ago

Just replace import 'roslib/build/roslib' with import 'roslib/build/roslib'只需将 import 'roslib/build/roslib' 替换为 import 'roslib/build/roslib'

Is there any difference?