Cloud-Automation / node-modbus

Modbus TCP Client/Server implementation for Node.JS
465 stars 174 forks source link

Proposal: TypeScript Support #239

Closed alexbuczynsky closed 4 years ago

alexbuczynsky commented 5 years ago

Is there any interest in typescript support for this library?

I can see two steps potentially.

I could see a couple benefits to incroporate at least step 1:

  1. Provides types for function arguments and responses
  2. Allows typescript user to use this package

If step 2 has any interest, these are the additional benefits I could see:

  1. Can target older versions of node that do not support promises by transpiling.
  2. Typescript supports abstract classes, so since the codebase uses the abstract ModbusClient for both the RTU and TCP clients, it would be easier to check the abstractions compliance before even running tests.

I would be happy to add a pull request if there is any interest in this / approval from the maintainer(s).

alexbuczynsky commented 5 years ago

We could also just imbed the typings directly in the project.

stefanpoeter commented 5 years ago

Hey @alexbuczynsky,

thanks for your Input. I personally do not use typescript but if you see the need for this I won't be in your way. Just make sure that the module stays compatible. :-)

alexbuczynsky commented 5 years ago

Hey @stefanpoeter

I converted the library into typescript. All your original tests are passing according to travis CI. You can see the changes at this branch: alexbuczynsky/node-modbus:typescript-support

I want to discuss a couple of things. Since you said yourself that you do not use TypeScript I would assume you would not want to potentially merge these changes since the source code would be in typescript completely. Keep in mind that the published npm version would be still vanilla javascript. If however, you do, we could bump the change to v3.2.0 since I added some new features and consistency in the responses mentioned in #229.

Alternatively, I could release an npm package called tsmodbus (sister to jsmodbus but in typescript) that would mirror the future changes and additions you would add to this module but be written in typescript to have nice things such as intellisense support in modern editors.

alexbuczynsky commented 5 years ago

This is the intellisense feature I am talking about shown running in vscode in the tcp-client test script. It helps to alleviate the confusion people are having when they are console logging the response and only seeing the private values, when the public readonly get methods are much easier to use. intellisense-node-modbus

stefanpoeter commented 5 years ago

Hi @alexbuczynsky

first of all, thanks for your commitment. :-)

Since I don't know Typescript I am curious how you build your library?

I assume you used some sort of conversion/compiler tool to transform the javascript base into typescript? How much effort did you spend converting the code? Is it possible to create the typescript library dynamically from this source?

My thoughts: When publishing your code as V3.2.0 (It would make better sence to let it be V4.0.0 since this is basically a complete reimplementation) then the Name jsModbus would be obsolete since this is not a javascript module anymore. I don't know what consequences this will bringt in since I assume there must be some sort of TS->JS Compiler before using this in node.js? This approach does not feel right, cannot quantify why at the moment.

If you go and publish your own tsModbus library we do not benefit from future updates.

I could imagine a third approach in which we build the TypeScript code dynamically, which I don't know anything about, what do you think?

alexbuczynsky commented 5 years ago

Hey @stefanpoeter,

Thanks for the reply. I will try to answer your questions below:

What is typescript at a 1000ft level

TypeScript is a superset of JavaScript which primarily provides optional static typing, classes and interfaces. One of the big benefits is to enable IDEs to provide a richer environment for spotting common errors as you type the code. link to further info

How the typescript library was built

Since I don't know Typescript I am curious how you build your library? I assume you used some sort of conversion/compiler tool to transform the javascript base into typescript? How much effort did you spend converting the code? Is it possible to create the typescript library dynamically from this source?

Although there are some conversion tools to help with the transition process (for example js-to-ts-converter), the bulk of the types (especially the more advanced types included in abstract classes) need to still be declared by hand which is what I did in my branch.

For example, a simple case when converting let's say the buffer-utils.js file to buffer-utils.ts would look like the following:

In vanilla javascript: javascript And in typescript: typescript

Keep in mind the above example was one of the easiest conversions, but the idea is that when compiling to javascript this steps provides type safety similiar to languages such as java or c#.

Naming convention of jsmodbus / compilation steps.

...the Name jsModbus would be obsolete since this is not a javascript module anymore. I don't know what consequences this will bringt in since I assume there must be some sort of TS->JS Compiler before using this in node.js?

The name can still remain the same since typescript is just a superset of javascript. I only introduced the new name if there needed to be two seperate packages.

When installing this npm package the end user can still use javascript or typescript to write their code just as they always have. When you publish a typescript package to npm, the compilation process (TS -> JS) happens first and adds the source code to a dist folder. Then only the dist folder, package.json and the README.md are uploaded to the npm repository. There is actually a hidden benefit here. Typescript allows us to target older versions of ecmascript, so we could technically support older versions of node.js before they introduced promises (all the way back to es3). This allows us to write our code in modern versions of ecmascript but compile to older versions if needed.

So basically nothing changes for the install process for existing users of jsmodbus, only for the npm publishing scripts which I have already included in my repository.

Here is an example of the dist folder:

image

The type definitions live right next to the original javscript with a map that maps the code to the type definitions.

Here is the decleration file (buffer-utils.d.ts) file for example: buffer-utilis.d.ts And the actual javascript code: carbon (8)

Building typescript code dynamically

I could imagine a third approach in which we build the TypeScript code dynamically, which I don't know anything about, what do you think?

As per my discussion above, the following question is kind of answered but I will rehash it here. I would propose the library source code be written in typescript, but the compiled distribution code is in javascript.

Let me know if this helps / if you have any questions.

alexbuczynsky commented 5 years ago

For those interested, here is an example of the source code that would be published to npm (created by running npm pack) https://drive.google.com/open?id=1IyADY5t-zwS-cpPtt5rG3R1t_OKql6yv

stefanpoeter commented 5 years ago

Thanks for the detailed explanation @alexbuczynsky,

I think we will make this the v4.0 of the modbus library since I like the approach. I will open up a new v4.0-dev branch as soon as I can and make you an collaborator. There are some issues lying around that I also want to address in v4.0, basically minor ones but still.

I'll get back to you, great work!

alexbuczynsky commented 5 years ago

Sweet! Sounds good.

stefanpoeter commented 5 years ago

@alexbuczynsky

I created a v4.0-dev branch and added you as a collaborator. Please post your code to the branch and I'll collect some more issues that I want to address in the new release. Happy coding.