qr-code-styling icon indicating copy to clipboard operation
qr-code-styling copied to clipboard

Node.js support

Open tejasxo opened this issue 6 years ago • 24 comments

Hey, I'm building a mobile application using flutter, I'm planning on using google cloud functions to build the QR code and relay it to the app as a png/svg. Is there any way I can use this with node.js?

tejasxo avatar Sep 08 '19 22:09 tejasxo

Hi @tvajjhala Thank you for your question! Currently, this lib doesn't support node environment, it requires DOM functions. But I am planning to add support of such feature in future releases.

kozakdenys avatar Sep 09 '19 07:09 kozakdenys

Hi! I'm interested in that support. Any news on this regard? May I help you with this development?

gabrielvega avatar Jul 07 '20 01:07 gabrielvega

Hi @gabrielvega Thanks for reaching out, I will take a closer look at this issue and let you know, how you can help me with this.

kozakdenys avatar Jul 07 '20 05:07 kozakdenys

Hi @kozakdenys, I made a workaround with puppeteer, not the best solution but it's working so far.

I'm thinking to spend hours of development work under your direction, you create the design and I can implement it. I don't have too much knowledge in this kind of developments so if you can give me some directions I will be happy and thrilled to do it!

The cool factor of your work is that you actually modify the QR depending on the logo you place in the middle, others solutions just place one image over the other and the QR code can be useless on different scenarios.

Let me know if this works for you. Best regards`

gabrielvega avatar Jul 08 '20 18:07 gabrielvega

any news reguarding nodeJs support?

mr-piratman avatar Feb 06 '21 15:02 mr-piratman

Hi @kozakdenys, I made a workaround with puppeteer, not the best solution but it's working so far.

I'm thinking to spend hours of development work under your direction, you create the design and I can implement it. I don't have too much knowledge in this kind of developments so if you can give me some directions I will be happy and thrilled to do it!

The cool factor of your work is that you actually modify the QR depending on the logo you place in the middle, others solutions just place one image over the other and the QR code can be useless on different scenarios.

Let me know if this works for you. Best regards`

Can you please explain the process for doing so? I also wanted to run this package in a node environment. Thank you in advance.

nishagr avatar Feb 10 '21 20:02 nishagr

@mr-piratman @nishagr, sorry, but no luck with node support yet. It turned out a more difficult task than I expected so I postponed it.

kozakdenys avatar Feb 11 '21 08:02 kozakdenys

I guess I'll must using it on the client side. Thank you in any way. Amazing library. 🍻

mr-piratman avatar Feb 11 '21 09:02 mr-piratman

Thanks for this library, I'm also looking for a NodeJS solution but Puppeteer is a good idea for a workaround!

Best looking QR codes I've found so far

LAMike310 avatar Mar 01 '21 18:03 LAMike310

@LAMike310 Can you please let me know how to use the Puppeteer workaround? Thank you.

nishagr avatar Mar 02 '21 08:03 nishagr

I needed this so I implemented it in my PR.

Basically supports BYO node-canvas, as it's not very portable and best to leave it to the end-developer to set up and to pass through. It also means it won't be included in any bundle for browser implementations.

Doing it this way means you can get it working in something like a lambda endpoint.

mrfrase3 avatar Mar 24 '21 10:03 mrfrase3

@LAMike310 Can you please let me know how to use the Puppeteer workaround? Thank you.

I ended up doing this:

Starting a server on Digital Ocean Create a "Create React App" with a react-router template on the server Implement the React library of to display QR codes dynamically Configure the React app to accept parameters (www.exapmle/[QR_DATA])) Run the React App locally on your server, port 3000 Use puppeteer to take a screenshot on a simple Express app running on port 3001

(async () => {
        const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});
        const page = await browser.newPage();
        page.setViewport({width: 600, height: 600 });

        await page.goto(`http://localhost:3000/reward/${id}`);

        await page.screenshot({
            path: `screenshot/qrCode-${imageID}.png`,
        });
        await browser.close();
})();

LAMike310 avatar Mar 28 '21 17:03 LAMike310

@mrfrase3's PR has been open with no update for 2 months now, any updates on this? Would really love this feature

randomprogramming avatar May 14 '21 21:05 randomprogramming

I got it working by using this forked package: https://www.npmjs.com/package/qr-code-styling-node

I needed some additional code though to make it work:

// This part is required before importing qr-code-styling-node
// https://github.com/kozakdenys/qr-code-styling/issues/9
import 'node-self';
global.window = new JSDOM().window as any;
global.self = global.window;
global.document = global.window.document;
// Only necessary when using "canvas" as image type iirc
// global.Image = (Canvas as any);
global.XMLSerializer = global.window.XMLSerializer;
import QRCodeStyling from "qr-code-styling-node";

const qrCode = new QRCodeStyling({
  width: 256,
  height: 256,
  jsdom: JSDOM as any,
  type: "svg", // canvas doesn't seem to make a difference
  data: "some data",

  // I used the datauri package to convert my logo
  image: "some data uri",
  // ...
});

// .png export doesn't work, no matter what I do.
const svgBuffer = await qrCode.getRawData("svg") as Buffer;

// As a workaround, I converted the result using the svgexport package
fs.createWriteStream("temp.svg").write(svgBuffer);

svgexport.render([
  {
    input: [pathFileTemp],
    output: [pathFile]
  }
]);

ciriousjoker avatar Oct 01 '21 10:10 ciriousjoker

@CiriousJoker I've tried to follow your steps creating a Cloud Function in Typescript but I only get an ReferenceError: self is no defined, on your package r-code-styling-node/lib/qr-code-styling.js:1:208).

Any idea around this? Has to be something related to global.self = global.window or node environment? I am stuck on this.

Thank you!

franzenitlab avatar Oct 01 '21 20:10 franzenitlab

@franzenitlab I fixed the code, my bad.

ciriousjoker avatar Oct 02 '21 00:10 ciriousjoker

I got it working by using this forked package: https://www.npmjs.com/package/qr-code-styling-node

I needed some additional code though to make it work:

// This part is required before importing qr-code-styling-node
// https://github.com/kozakdenys/qr-code-styling/issues/9
import 'node-self';
global.window = new JSDOM().window as any;
global.self = global.window;
global.document = global.window.document;
// Only necessary when using "canvas" as image type iirc
// global.Image = (Canvas as any);
global.XMLSerializer = global.window.XMLSerializer;
import QRCodeStyling from "qr-code-styling-node";

const qrCode = new QRCodeStyling({
  width: 256,
  height: 256,
  jsdom: JSDOM as any,
  type: "svg", // canvas doesn't seem to make a difference
  data: "some data",

  // I used the datauri package to convert my logo
  image: "some data uri",
  // ...
});

// .png export doesn't work, no matter what I do.
const svgBuffer = await qrCode.getRawData("svg") as Buffer;

// As a workaround, I converted the result using the svgexport package
fs.createWriteStream("temp.svg").write(svgBuffer);

svgexport.render([
  {
    input: [pathFileTemp],
    output: [pathFile]
  }
]);

I tried it and got this error :

(node:2370) UnhandledPromiseRejectionWarning: TypeError: qr_code_styling_node_1.default is not a constructor

nasrulfuad avatar Oct 22 '21 03:10 nasrulfuad

I successfully transpile the code to run on a server with the canvas's package ! I already test it, I just cannot build svg version (didn't see how the project runs to export a svg image)

I would like to share my code but my code is really ugly ^^' (I remove all the test unit + configurations files)

Here is the result:

import NodeQRCodeStyling from "./core/NodeQRCodeStyling";

const qr = new NodeQRCodeStyling({
  width: 300,
  height: 300,
  data: "https://qr-code-styling.com",
  qrOptions: { typeNumber: 0, mode: "Byte", errorCorrectionLevel: "H" },
  imageOptions: { hideBackgroundDots: true, imageSize: 0.4, margin: 15 },
  dotsOptions: { type: "dots", color: "#000000", gradient: null },
  backgroundOptions: { color: "#ffffff" },
  image: "https://cdn.pixabay.com/photo/2015/05/17/10/51/facebook-770688_1280.png",
  cornersSquareOptions: { type: "extra-rounded", color: "#000000" },
  cornersDotOptions: { type: "dot", color: "#000000" }
});

(async () => {
  const canvas = await qr.draw();

  console.log(canvas.toDataURL());
})();

dupasj avatar Nov 24 '21 13:11 dupasj

The QR-codes generated by this library looks really cool, it's sad that there's no Node.js support, we would definitely like to use it in our server-side application.

slavafomin avatar Sep 03 '22 18:09 slavafomin

@mr-piratman @nishagr, sorry, but no luck with node support yet. It turned out a more difficult task than I expected so I postponed it.

Is it released yet?

sunny-2504 avatar Sep 05 '22 08:09 sunny-2504

For future reference guys, I used this package and works like a charm. https://socket.dev/npm/package/@loskir/styled-qr-code-node

rafagomes avatar Mar 21 '23 18:03 rafagomes

@kozakdenys or anyone else. Have you been able to build this without the need for rust or puppeteer? I'm looking to deploy this to a node server that has been limited and can't execute external code or other languages. So the index.node c++ rust process causes it it to fail with error: /var/task/node_modules/skia-canvas/lib/v6/index.node: invalid ELF header.

I also can't launch a headless chrome window.

Any help you all can provide would be greatly appreciated.

themaniacalfry avatar Jul 16 '23 17:07 themaniacalfry

I got it working by using this forked package: https://www.npmjs.com/package/qr-code-styling-node

I needed some additional code though to make it work:

// This part is required before importing qr-code-styling-node
// https://github.com/kozakdenys/qr-code-styling/issues/9
import 'node-self';
global.window = new JSDOM().window as any;
global.self = global.window;
global.document = global.window.document;
// Only necessary when using "canvas" as image type iirc
// global.Image = (Canvas as any);
global.XMLSerializer = global.window.XMLSerializer;
import QRCodeStyling from "qr-code-styling-node";

const qrCode = new QRCodeStyling({
  width: 256,
  height: 256,
  jsdom: JSDOM as any,
  type: "svg", // canvas doesn't seem to make a difference
  data: "some data",

  // I used the datauri package to convert my logo
  image: "some data uri",
  // ...
});

// .png export doesn't work, no matter what I do.
const svgBuffer = await qrCode.getRawData("svg") as Buffer;

// As a workaround, I converted the result using the svgexport package
fs.createWriteStream("temp.svg").write(svgBuffer);

svgexport.render([
  {
    input: [pathFileTemp],
    output: [pathFile]
  }
]);

This works great until I try and add an image. It appears to be hitting const svgBuffer = await qrCode.getRawData("svg") as Buffer; then breaking out of the process and not generating the SVG QR Code. Any ideas why?

{
    image: "https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg",
    imageOptions: {
        margin: 8,
        hideBackgroundDots: false
    },
    data: "some_data",
}

bigirishlion avatar Aug 05 '23 21:08 bigirishlion

For future reference guys, I used this package and works like a charm. https://socket.dev/npm/package/@loskir/styled-qr-code-node

+1 for this awesome fork! It works out of the box in Node.js without any other patching.

You can leave some stars for it here: https://github.com/Loskir/styled-qr-code

phgn0 avatar Jan 18 '24 13:01 phgn0