jimp icon indicating copy to clipboard operation
jimp copied to clipboard

Jimp Browser Support

Open marvinruder opened this issue 1 year ago • 28 comments

Is your feature request related to a problem? Please describe. At the moment, some problems arise when attempting to use Jimp in React (similar issues were reported from users of other tools, e.g. React Native). The following are known so far:

  • [ ] Jimp.read is undefined / not a function – can be avoided by using Typescript’s useModuleInterop: true, no fix yet for plain Javascript. Reproducable in jimp-dev/jimp-react. Might be related to #1191, #1178, #761.
  • [ ] process is not defined in browser console, caused by process.env.__TESTING_MKDIRP_PLATFORM__ in dependency mkdirp
  • [ ] When using the jimp/es import, accessing some built-in Node APIs like fs, path etc. is attempted and the build fails (example: Can't resolve 'fs' in '…/node_modules/@jimp/core/es'). Reproducable in jimp-dev/jimp-react

Describe the solution you'd like The issues described above are resolved and Jimp can be used in frontend tools like React using import Jimp from "jimp[/es]"; without a problem.

Describe alternatives you've considered Using the browser version of Jimp via require("jimp/browser/lib/jimp.js"); const { Jimp } = window; is a possible workaround, but that version is aimed more at using Jimp in plain HTML/JS than by bundling tools such as Webpack, Rollup etc., which should be able to handle jimp or jimp/es properly.

marvinruder avatar Feb 07 '23 20:02 marvinruder

image

sergeushenecz avatar Feb 07 '23 21:02 sergeushenecz

It might be worthwhile to explore an option similar to how @wmhilton has done so with isomorphic-git using FS as a property to pass in:

https://isomorphic-git.org/docs/en/fs#docsNav

@wmhilton has even created a browser-first FS package called "LighningFS" that might be a good package to point to for official browser support, alongside an example repo that integrates it:

https://github.com/isomorphic-git/lightning-fs

crutchcorn avatar Feb 07 '23 23:02 crutchcorn

Also worth mentioning - @marvinruder you may want to look into the work being done by @danielholmes :

https://github.com/danielholmes/jimp-vite

crutchcorn avatar Feb 07 '23 23:02 crutchcorn

It can work well on example, this lib using for node so some related packages don't work you need to use a build for the browser version and then I have resolved this and workaround by loading jimp.js on index.html and defining a global type for Jimp variable

suneox avatar Feb 08 '23 02:02 suneox

Yeah that one works but we're talking about esm usage rather than bundling. Bundling means we can't tree shake things. Right now our esm breaks browsers

hipstersmoothie avatar Feb 08 '23 03:02 hipstersmoothie

When using the jimp/es import, accessing some built-in Node APIs like fs, path etc. is attempted and the build fails (example: Can't resolve 'fs' in '…/node_modules/@jimp/core/es'). Reproducable in jimp-dev/jimp-react

I'm having this issue too, is a solution in the works or is there a specific suggested workaround?

gabycush avatar Feb 16 '23 09:02 gabycush

My solution for NextJS was to load jimp and import from window, similar approach from the issue's text but not using the library for the browser (it was giving me the error that self is not defined).

Code:

import 'jimp';
const { Jimp } = window as any;

Hope it helps anyone

Ronkiro avatar Mar 01 '23 03:03 Ronkiro

My solution for NextJS was to load jimp and import from window, similar approach from the issue's text but not using the library for the browser (it was giving me the error that self is not defined).

Code:

import 'jimp';
const { Jimp } = window as any;

Hope it helps anyone

This really helps me to get through this issue for now! Struggled for a few hours, thanks!

angello0926 avatar Apr 02 '23 20:04 angello0926

I tried all the suggestions, but still couldn't make it work... I'm trying to use Jimp in a Web Worker, with Vite. So, I'm not being able to use the lib. I'd even help with this bug, but I don't know where to start right now.

MBrunoS avatar Apr 08 '23 01:04 MBrunoS

I got Jimp working in the browser/webworker/node/... with this ugly hack:

ES6:

// For some reason, Jimp attaches to self, even in Node.
// https://github.com/jimp-dev/jimp/issues/466
import * as _Jimp from 'jimp';

// @ts-ignore
const Jimp = (typeof self !== 'undefined') ? (self.Jimp || _Jimp) : _Jimp;

CommonJS:

// For some reason, Jimp attaches to self, even in Node.
// https://github.com/jimp-dev/jimp/issues/466
const _Jimp = require('jimp');

// @ts-ignore
const Jimp = (typeof self !== 'undefined') ? (self.Jimp || _Jimp) : _Jimp;

xenova avatar Apr 09 '23 17:04 xenova

@xenova I don't know why this works, but it works.

I've been struggling to get Jimp working on Cloudflare Workers (using SvelteKit) for wayyy too long and you're solution just works.

One thing I noticed using your solution is instantiating a new Jimp instance I have to do new Jimp.default(...) on Node.js but on Cloudflare Workers new Jimp(...) is the only way that works.

I am extremely grateful that you shared your solution, so thanks <3.

sexnine avatar Apr 09 '23 19:04 sexnine

I don't know why this works, but it works.

That's exactly what I thought when I got it working 🤣 ...

One thing I noticed using your solution is instantiating a new Jimp instance I have to do new Jimp.default(...) on Node.js but on Cloudflare Workers new Jimp(...) is the only way that works.

Interesting. I haven't had an issue with creating new Jimp instances with my node.js version... but it's good to know you found a solution!

I am extremely grateful that you shared your solution, so thanks <3.

Happy to help!

xenova avatar Apr 09 '23 19:04 xenova

My solution for NextJS was to load jimp and import from window, similar approach from the issue's text but not using the library for the browser (it was giving me the error that self is not defined).

Code:

import 'jimp';
const { Jimp } = window as any;

Hope it helps anyone

Ok but, where is that code supposed to go inside the next Js project? In the component that's gonna use Jimp?

LetMeDream avatar Apr 13 '23 00:04 LetMeDream

I got Jimp working in the browser/webworker/node/... with this ugly hack:

ES6:

// For some reason, Jimp attaches to self, even in Node.
// https://github.com/jimp-dev/jimp/issues/466
import * as _Jimp from 'jimp';

// @ts-ignore
const Jimp = (typeof self !== 'undefined') ? (self.Jimp || _Jimp) : _Jimp;

CommonJS:

// For some reason, Jimp attaches to self, even in Node.
// https://github.com/jimp-dev/jimp/issues/466
const _Jimp = require('jimp');

// @ts-ignore
const Jimp = (typeof self !== 'undefined') ? (self.Jimp || _Jimp) : _Jimp;

This works in Next JS and apps created using CRA. Not in Vite, tho.

LetMeDream avatar Apr 13 '23 18:04 LetMeDream

No luck when using it in a webpage in a typescript project:

[vue warn]: Error in v-on handler (Promise/async): "TypeError: jimp__WEBPACK_IMPORTED_MODULE_7___default(...) is not a function"

found in

---> <VBtn>
       <GenericViewer> at src/components/vehiclesetup/viewers/GenericViewer.vue
         <VehicleViewer> at src/components/vehiclesetup/viewers/VehicleViewer.vue
           <VCard>
             <SetupOverview> at src/components/vehiclesetup/SetupOverview.vue
               <VehicleSetupView> at src/views/VehicleSetupView.vue
                 <VMain>
                   <VApp>
                     <App> at src/App.vue
                       <Root>

w

patrickelectric avatar Apr 21 '23 17:04 patrickelectric

I got Jimp working in the browser/webworker/node/... with this ugly hack:

ES6:

// For some reason, Jimp attaches to self, even in Node.
// https://github.com/jimp-dev/jimp/issues/466
import * as _Jimp from 'jimp';

// @ts-ignore
const Jimp = (typeof self !== 'undefined') ? (self.Jimp || _Jimp) : _Jimp;

CommonJS:

// For some reason, Jimp attaches to self, even in Node.
// https://github.com/jimp-dev/jimp/issues/466
const _Jimp = require('jimp');

// @ts-ignore
const Jimp = (typeof self !== 'undefined') ? (self.Jimp || _Jimp) : _Jimp;

Because some were wondering why your proposed workaround works: I just did a little digging, because I had the same issue. I found this in the @jimp/core/ index.js (in both es and dist); it is before the last three lines of code in those files:

if (process.env.ENVIRONMENT === "BROWSER") {
  // For use in a web browser or web worker
  /* global self */
  let gl;
  if (typeof window !== "undefined" && typeof window === "object") {
    gl = window;
  }
  if (typeof self !== "undefined" && typeof self === "object") {
    gl = self;
  }
  gl.Jimp = Jimp;
  gl.Buffer = Buffer;
}

I don't know why and I don't think I will look into it, but maybe this will give the right person a starting idea on where to look to resolve this issue.

Lofavreel avatar May 07 '23 18:05 Lofavreel

Any help from someone in the community would be appreciated. If you want to submit a PR I'd be happy to Shepard that PR. At the time unfortunately I don't see myself doing this soon.

hipstersmoothie avatar May 11 '23 01:05 hipstersmoothie

Just for others usign React, the workaround mentioned on the issue's text worked for me:

export default function App() {
    require("jimp/browser/lib/jimp.js"); 
    const { Jimp } = window
    ...
};

this also worked:

import 'jimp';

export default function App() {
    const { Jimp } = window;
    ...
};

jcard0na avatar May 11 '23 11:05 jcard0na

My solution for NextJS was to load jimp and import from window, similar approach from the issue's text but not using the library for the browser (it was giving me the error that self is not defined). Code:

import 'jimp';
const { Jimp } = window as any;

Hope it helps anyone

This really helps me to get through this issue for now! Struggled for a few hours, thanks!

Thanks for this suggestion. This worked for me.

devenkhatri avatar Jun 01 '23 15:06 devenkhatri

For Vercel edge the workaround mentioned by @xenova works locally but not on production and even locally you have to set unstable_allowDynamic and point it to the library in node_modules but that doesn't seem to work for some reason when trying to deploy to production.

da7a90-backup avatar Jun 02 '23 20:06 da7a90-backup

My solution. Version 0.22.10

import  'jimp/browser/lib/jimp';
const { Jimp } = window;

sergeushenecz avatar Sep 03 '23 08:09 sergeushenecz

none of these work very well for typescript...

meepen avatar Nov 02 '23 20:11 meepen

none of these work very well for typescript...

@meepen check my comment https://github.com/jimp-dev/jimp/issues/1194#issuecomment-1449287374 it may help you

Ronkiro avatar Nov 07 '23 14:11 Ronkiro

For react native/expo with hermes engine, this actually works, I cannot understand why it is like that, any insigths would be very helpful.

import * as _Jimp from 'jimp';
const Jimp = (typeof self !== 'undefined') ? (self.Jimp || _Jimp) : _Jimp;

sameert89 avatar Nov 18 '23 07:11 sameert89

@sameert89 React Native newbie here, but it seems that self works like window for RN. This snippet checks if it's existent/accessible, if it is then use it, else use the normal variable. It's similar to the solution i pointed https://github.com/jimp-dev/jimp/issues/1194#issuecomment-1449287374 and to the one pointed in the first post

Ronkiro avatar Dec 06 '23 14:12 Ronkiro

none of these work very well for typescript...

Maybe try this:

import "jimp";

const ReactComponent = () => {
  const { Jimp } = window as Window & typeof globalThis & {
    Jimp: typeof import("jimp");
  };
...

NayamAmarshe avatar Dec 28 '23 13:12 NayamAmarshe

For react native/expo with hermes engine, this actually works, I cannot understand why it is like that, any insigths would be very helpful.

import * as _Jimp from 'jimp';
const Jimp = (typeof self !== 'undefined') ? (self.Jimp || _Jimp) : _Jimp;

I was very excited to find this comment, since I am also trying to use Jimp in React Native (w/o Expo), but it does not work for me. Or it partly works, in that I can use the constructor to create an object to receive an image:

const jp = new Jimp(256, 256, "#000000", (err, image) => {
  console.log("+++", err);
});

But I can't seem to use that value to access functionality like Jimp.read() which is what I need.

tsgouros avatar Mar 21 '24 01:03 tsgouros

For those want to use jimp in browser with typescript definition, here's a guide. First, import browser build. As it pollute into window.Jimp, place doesn't matter.

import 'jimp/browser/lib/jimp.js'

Then, add a dts file

declare var Jimp: typeof import('jimp')

Just use Jimp.xxx.

neko-para avatar Apr 13 '24 12:04 neko-para

@sexnine Can you please prove the example code for Cloudflare? I can't get it work for some reason.

vickyRathee avatar Apr 23 '24 07:04 vickyRathee

@sexnine Can you please prove the example code for Cloudflare? I can't get it work for some reason.

Are you using Sveltekit on CF workers, or just vanilla workers? Typescript or JS?

I can try to make a quick demo later today :)

sexnine avatar Apr 23 '24 07:04 sexnine