JsBarcode icon indicating copy to clipboard operation
JsBarcode copied to clipboard

New major version (4.0) discussion

Open SanichKotikov opened this issue 5 years ago • 39 comments

@lindell Hi,

Some questions about next version:

  • do you wanna keep jQuery support?
  • do you wanna keep html element's properties (as options for a barcode) support?
  • do you wanna keep *.min.js files (cdn links), to use the library without npm?
  • do you wanna keep bower support?

Any other thoughts about next major version?

SanichKotikov avatar Sep 02 '18 07:09 SanichKotikov

  • I think jQuery support may be dropped. It's not like someone can't use it without it.
  • I think it's a good thing. Personally, I like specifying it with the JS options but it was a highly requested feature before it was implemented.
  • Unfortunately a lot of websites still hasn't migrated to the new world of web development where you use package managers (>20,000,000 downloads of JsBarcode each month this way). Therefore I'm not sure about it, even if I would like to remove it. One solution might just be to say to people that wan't CDN support to use version 3.
  • We should drop bower support

lindell avatar Sep 02 '18 08:09 lindell

Also, if we drop the CDN support. We could remove the not so nice gulp scripts.

lindell avatar Sep 02 '18 08:09 lindell

Something I would like to do in the next version it support better tree shaking. The problem is that it would require an API that is not as clean (as I see it).

I imagine something like this.

import jsbarcode, { code128, canvasRenderer } from 'jsbarcode';

jsbarcode(value, element, {
  format: code128,
  render: canvasRenderer,
});

I think this will work in webpack 4 but not in the lower versions.

To support lower versions I think this will be needed

import jsbarcode from 'jsbarcode';
import code128 from 'jsbarcode/format/code128';
import canvasRenderer from 'jsbarcode/render/canvas';

jsbarcode(value, element, {
  format: code128,
  render: canvasRenderer,
});

In either case, no default value for the format or renderer may be set.

lindell avatar Sep 02 '18 09:09 lindell

I see, thanks. Now I know that my thoughts close with yours :) I'll try to think about how to make it all works, if you don't mind. Not right now, of course :)

SanichKotikov avatar Sep 02 '18 14:09 SanichKotikov

Here is another good point https://github.com/lindell/JsBarcode/issues/273

SanichKotikov avatar Nov 19 '18 08:11 SanichKotikov

I will slowly begin to rewrite jsbarcode now. Will post when I have something to show 🙂

lindell avatar Nov 26 '18 20:11 lindell

I've made some changes now that should be a start to JsBarcode 4.

The answers to all the question in the first post are no. I've been thinking about it, and I want to keep the core as simple as possible so that it can easily be expanded on outside of this library if someone needs it. And also to keep the impact of using the library as small as possible.

Here is an example https://github.com/lindell/JsBarcode/blob/jsbarcode-v4/example/index.js the structure is not correct but used what I had to get something to work as quickly as possible (and enable code splitting). Building is done with npm run build

lindell avatar Jan 19 '19 08:01 lindell

@lindell wow, great work! Thx.

as small as possible

👍

I'll try it in my project.

SanichKotikov avatar Jan 19 '19 14:01 SanichKotikov

With new API you can create your custom JsBarcode function:

import flatEncodings from '../lib/help/linearizeEncodings';
import EAN13 from '../lib/barcodes/EAN_UPC/EAN13';
import SVGRender from '../lib/renderers/svg';

const options = {
    width: 2,
    height: 100,
    displayValue: true,
    fontOptions: '',
    font: 'monospace',
    textMargin: 2,
    fontSize: 20,
    margin: 10,
    marginTop: 10,
    marginBottom: 10,
    marginLeft: 10,
    marginRight: 10,
};

const encoder = new EAN13('9780199532179', options);

if (encoder.valid()) {
    const svg = document.querySelector('#barcode');
    const encodings = flatEncodings(encoder.encode());
    new SVGRender(svg, encodings, options).render();
}

SanichKotikov avatar Jan 20 '19 07:01 SanichKotikov

You can even use promises 😁 :

import flatEncodings from '../lib/help/linearizeEncodings';
import EAN13 from '../lib/barcodes/EAN_UPC/EAN13';
import SVGRender from '../lib/renderers/svg';

const OPTIONS = {
    width: 2,
    height: 100,
    displayValue: true,
    fontOptions: '',
    font: 'monospace',
    textMargin: 2,
    fontSize: 20,
    margin: 10,
    marginTop: 10,
    marginBottom: 10,
    marginLeft: 10,
    marginRight: 10,
};

function barcode(element, text, options) {
    return new Promise((resolve, reject) => {
        options = { ...OPTIONS, ...options };
        const encoder = new EAN13(text, options);

        if (encoder.valid()) {
            const encodings = flatEncodings(encoder.encode());
            new SVGRender(element, encodings, options).render();
            resolve();
        } else {
            reject(new Error('Invalid data'));
        }
    });
}

// usage

(async function() {
    try {
        const svg = document.querySelector('#barcode');
        await barcode(svg, '978019953217', { textMargin: 0 });
        // do something next
    } catch (error) {
        // handle errors
    }
})();

SanichKotikov avatar Jan 20 '19 07:01 SanichKotikov

Yes, everything will become much more modularized :) It will also be much easier to create your own renderer or barcode without having it as a part of jsbarcode.

lindell avatar Jan 20 '19 09:01 lindell

That's nice, but the promise part is not even necessary :) (since nothing in jsbarcode is asynchronous )

import flatEncodings from '../lib/help/linearizeEncodings';
import EAN13 from '../lib/barcodes/EAN_UPC/EAN13';
import SVGRender from '../lib/renderers/svg';

const OPTIONS = {
    width: 2,
    height: 100,
    displayValue: true,
    fontOptions: '',
    font: 'monospace',
    textMargin: 2,
    fontSize: 20,
    margin: 10,
    marginTop: 10,
    marginBottom: 10,
    marginLeft: 10,
    marginRight: 10,
};

function barcode(element, text, options) {
    options = { ...OPTIONS, ...options };
    const encoder = new EAN13(text, options);

    if (encoder.valid()) {
        const encodings = flatEncodings(encoder.encode());
        new SVGRender(element, encodings, options).render();
    } else {
        throw new Error('Invalid data');
    }
}

// usage

try {
    const svg = document.querySelector('#barcode');
    barcode(svg, '978019953217', { textMargin: 0 });
    // do something next
} catch (error) {
    // handle errors
}

lindell avatar Jan 20 '19 09:01 lindell

@lindell I've tried to install 4.0.0-alpha.2 and there is no lib directory.

SanichKotikov avatar Jan 20 '19 11:01 SanichKotikov

I will have a look at it!

lindell avatar Jan 20 '19 15:01 lindell

4.0.0-alpha.4 have the lib folder 🙂

lindell avatar Jan 20 '19 20:01 lindell

Some things needs to be decided before we can publish the first beta of v4. First, what should we call encoder and renderer? I think the renderer name is pretty good. But I'm not sure about the encoder name, other alternatives are format and barcode.

I'm also thinking about changing the renderer and barcodes from classes to functions since I don't see any reason for them to be classes that is instantiated. The problem is that the barcodes has valid function that is also used right now, two alternatives there is to let the barcode throw the InvalidInputException themselfs, or use a {encode: func, valid: func} structure instead

lindell avatar Jan 21 '19 18:01 lindell

The encoder name is obvious for me. Also some other libraries have the same name. The renderer is also good.

I also have a problem with valid function, I can't call it without instantiated a class. The first idea I have, it is to create that method static. But migrating to functions might be a better idea, make the code more declarative.

SanichKotikov avatar Jan 21 '19 18:01 SanichKotikov

Also I thought about typescript 😅but I don't have time for that 😔

SanichKotikov avatar Jan 21 '19 18:01 SanichKotikov

A feature I sought out for a while was how to render a barcode inside javascript to use it with jspdf. I got around it using const canvas = document.createElement('canvas') but I would love to see a callback function to put a blob/url to use as an image :)

halvardssm avatar Jan 31 '19 19:01 halvardssm

@halvardssm To get a base64 encoded blob with jsbarcode is already very simple and is not something that will be added to jsbarcode 4. The goal with it is to strip out as much as possible that can be done easily anyways,

Code for JsBarcode 3:

function textToBase64BarcodeBlob(text){
  const canvas = document.createElement("canvas");
  JsBarcode(canvas, text);
  return canvas.toDataURL("image/png");
}

lindell avatar Jan 31 '19 19:01 lindell

Hi, just started using you lib, and have some issues when i installed via yarn, it grabbed "^4.0.0-alpha.5" which i am assuming is still in dev going by this thread

lgrayland avatar Feb 16 '19 17:02 lgrayland

Hey, I just ran across this thread and I though I suggest things, if this is open to conversation?

@SanichKotikov asked four things:

do you wanna keep jQuery support?

I would say that it is a good thing if you keep jQuery as it is still a really present library on the web. As of today (2019-02-23) it still accounts for 11% of JavaScript most use library in the top 1 million web site.

On personal experience, I used this library in a project a while ago when I was only starting as a developer. Using it with jQuery made my life WAAAAY easier.

do you wanna keep html element's properties (as options for a barcode) support?

If it is an hassle or way too complex for what it really brings to the library, I would drop it, otherwise I would keep it as it gives the developer another option on how to use the library. With the growing number of library that implement a component-based approach (React, Vuejs, Angular, etc), setting up the library within a component definition is an advantage. Well, I see it as an advantage :P

do you wanna keep *.min.js files (cdn links), to use the library without npm?

As @lindell mentionned:

Unfortunately a lot of websites still hasn't migrated to the new world of web development where you use package managers (>20,000,000 downloads of JsBarcode each month this way). Therefore I'm not sure about it, even if I would like to remove it. One solution might just be to say to people that wan't CDN support to use version 3.

And I very much agree with him.

He also stated that:

Also, if we drop the CDN support. We could remove the not so nice gulp scripts.

When things get too complex for what they really bring up, we tend to botch it. What is the real value of this "feature"? Maybe you could do a little survey on your users? I am even willing to give a hand with this!

do you wanna keep bower support?

I personnaly think you should drop it as it adds works for the developer of this library as well as it is less and less used in project.

See also.

My 2 cents

NPM Scoped Package

If I were to build this great library I would definitely go for a scoped package (see here). You could split each codebar into a different codebar implementation into it's own package within this scoped package. That is also a good alternative to CDN's. Another good reason to do so is to split the workload. If you have some contributors, it's easier to have them maintain or contribute on a certain package.

The only problem I see with this is the dependency hell. But with little management can this problem be avoided.

This tread asked for this feature, @lindell mentionned this is planned, I just specify scoped package would be the way to go ;)

Examples
// Core functionalities
@jsBarcode/core

 // Get all sub-package
@jsBarcode/all

// Get sub-package only for code128. Requires @jsBarcode/core
@jsBarcode/code128
...

Conclusion

I think this library is really great! I believe that every choices made for developing it further will make it even greater. A

Let me know if I can contribute in any way!

Crackroach avatar Feb 23 '19 15:02 Crackroach

@lgrayland I will take a look at it. Thought alpha tags would not be used as default

lindell avatar Feb 25 '19 17:02 lindell

@Crackroach When it comes to jQuery support. What we mean is that it will not be unusable with jQuery. Just that you will have to write

JsBarcode("#id",

Instead of

$("#id").JsBarcode(

Do you see any reason to still keep it?

lindell avatar Feb 25 '19 18:02 lindell

When it comes to jQuery support. What we mean is that it will not be unusable with jQuery. Just that you will have to write

JsBarcode("#id",

Instead of

$("#id").JsBarcode(

Do you see any reason to still keep it?

@lindell To be honest, no I don't. What I stated was entierly based on personal experience. When I started to program I used jQuery as it (seemed it) was simpler than actual JS code. Your library actually manage to grab the element, so I don't think that would still be useful.

Crackroach avatar Feb 25 '19 18:02 Crackroach

@lgrayland npm apparently sets the latest tag to newly published version independent of the naming. It should be set on the last stable version again, and newly tagged alphas should not be tagged with the latest tag.

lindell avatar Feb 25 '19 18:02 lindell

can provide 'pt' for print diff dpi

Hi-NNN avatar Mar 26 '19 02:03 Hi-NNN

Perhaps this is not the thread for this "suggestion", but I would like to see if it is possible to have the option to have SVG elements or paths.

This is because I mainly use this library to embed the barcode in PDFs, I used pdfKit and pdfMake:

  • pdfKit is "easier" to embed the path barcode because it supports natively.
  • pdfmake requires converting to base64 in order to embed the barcode, so for this library is not a big deal anyway.

thanks!

jaguarxii avatar Apr 20 '19 15:04 jaguarxii

It would be nice for it to support 2D barcodes like PDF417, QR Codes, etc. Another nice thing would be a scanner feature.

ewliang avatar Aug 08 '19 17:08 ewliang

@lindell Code 39, mod43 typing is not included in jsbarcode.d.ts: CODE39(value: string, options?: Code39Options): api; interface Code39Options extends BaseOptions { mod43?: boolean; } should fix this

SK-Commit avatar Oct 01 '19 09:10 SK-Commit