-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: Limit size of the package for browser usage #156
Comments
dgram functionality is not possible from client as noted and is only part of the older upnp lookups, if you don’t use discovery, it does not feature. Node-mbed-dtls-client was only in play when I was evaluating supporting the entertainment api, it is not part of the dependencies, so not sure where this is coming from... is it in a old lock file? Get-ssl-certificate is required to retrieving the cert from the bridge and validating the client on a local network, I guess you are looking at using the remote api functionality, so these are valid external ssl certificates? Bottleneck was the smallest bandwidth limiting library I could find, but if you are using the remote api, thing will change a bit with respect to usage, although the overall limits are still valid to stay within the bridge limits for performance. I prefer to not use a dependency when I can implement the same in a smaller way with low or no dependencies, but the last two give a reasonable amount of functionality that I really don’t want to have to build/maintain myself. Can you clarify that your use case is a browser based client, using the remote api functionality? If so then I understand the desire to exclude dependencies that are not useful. I have kept in mind that minification will be useful for browser users, so avoid doing dynamic requires etc... to ensure things will able to be minimised correctly. I need to think on this a little, based off your answers, but we should be able to achieve some improvements for you. |
I have taken a look at the How are you minifiying the code? As others in the distant past have minified this code base for the browser usage and we worked through those issues successfully in the past (one of the reasons that pushed me over to using |
Currently I use webpack which bundles all |
Hi @peter-murray, thanks for you comment. I'll try to answer as good as possible.
Since discovery is part of the exported api, dgram is as well and need a workaround for webpack.
Good point. We can skip this. The main entry into this - the
This is a server-side only think I guess. In the browser the browser itself is checking the ssl certificate.
Thats a nice one, but I guess (at least for my usecase) this will be sufficient on server side only.
Sure, thats what I prefer also normally.
Does the above is enough explaination? I would like to have a PWA which requires a valid ssl domain. Therefore I cannot directly speak to the bridge, and the remote api directly does not support CORS and cannot secure the app credentials. Therefore I have a server-side part which will talk to the remote api, the client will use the server side 'mirror' (or proxy) of the api.
That sounds reasonable and good. Its hard to require from variables when you want to bundle something. |
Thanks, that provides me with some good context. This has been used in the browser before, I had a user utilizing it there, but that was under the I think the change to have If we look at the browser only uses case then you cannot access the Remote API directly, as CORS will prevent that from happening, hence your proxy service. In this case though you are not going to be instantiating a bridge, so the ssl certificate stuff would be dropped when you package your code, as it will not be used. The project is built to support Node.js as the primary use case and others as a nice to have, so things are driven from the Node.js language support first. Unfortunately Node.js is really dragging out the migration to ES6 modules and I would be extremely cautious of creating a dual CommonJS/ES Module Package as there can be some very difficult issues you can introduce to downstream users. I am also not a massive fan of compiling/transpiling JavaScript, but the community and browser based projects generally are. The whole point of JavaScript from me was avoiding the compilation (and verbosity) as I came from a Java background. It may be possible to provide a stripped down API separate to I will take a bit of time to look at what a stripped down browser client might look like and set up some tests with webpack and see what starts to fall out. I am happy to continue to work on this to find something that works and makes sense. |
So some quick findings: With a modified I applied a patch to remove I need to look at what is cuasing the library to be so large with packed, as I would have thought it would have come in a little lighter and I need to plan to spend time in the right areas where we can get the best return. |
In your use case, you have a proxy server. In the browser client side, you are not going to be creating a bridge instance, as you are talking to your proxy, not a bridge. Are you emulating the actual API endpoints of a Hue bridge in your proxy and instantiating a bridge instance in the client browser code? If not how are you doing this interaction, do you have your own custom endpoints and just passing the JSON payloads from the library? The addition of the ability to serialize to JSON and then reconstitute back to a model based object that was added in 4.x for your use case would only require the I think a lot of the size (just reading through the webpacked file) appears to be coming from various security and crypto components, and axios will be dragging in a lot of this too. |
I do exactly this. My server side does use the whole remove api while the client side will require only the deserialized model. The server serializes the json.
It would be great to have a 'lite' api, or just a model api. This should trim down the package size a lot. |
So I am on the fence with the model either becoming another module altogether (i.e. node-hue-api-model) or just being able to require it as a top level object from the If extracted to completely standalone it complicates the build/dependencies and development to a degree, if included, you will still have the dependencies showing up, but when webpacked, they should all be discarded. I just ran a quick test of webpack on the model itself and it comes in at 83kb if targeted directly for packing into a minimized module. What is your personal preference to this? Would having something like ;
work if I pulled that up from the existing Is having this webpacked in a |
Breaking up the model sound very good. I would say for ease of api handling keep it in the same package but the require statement need to be a bit different. This should work for webpack: const model = require('node-hue-api/model').v3; If you have it directly on the main, webpack will still bundle all the api, because commonjs is by its nature of dynamic not tree shakeable. I'm also more than happy to bundle/pack it on my side, webpack will do nonetheless. No need to prebundle it. |
I cannot find something I am happy with here that works across the mix of things we have in play here:
I have toyed with pulling out the model, types and placeholders in to a separate node module, but event then I am faced with having to invert all the code and rewrite it to use ESM and then compile back down to CJS. Due to the number of files involved here, that is a fairly heavy amount of work and something that does not really feeel worth the effort until Node.js properly catches up with ESM modules and I can cut support for the older LTS versions. The reason I lean this way is that browser usage of the library is significantly smaller than Node.js usage. Trying to tie in the TypeScript definitions is also tricky as the modules for Node.js and Browser end up being different, and I cannot find any easy way to support the generated TypeScript definitions across different modules (unless you write everything in TypeScript, which is a massive undertaking in itself, and not something I would enjoy doing). That leaves me with a possibility of generating bundled files in a Attached is an example of webpacked code that would be in the dist directory of a published npm package: Would that work for you? I really need to wait until we get an LTS version of Node.js that supports ESM before I want to invest a large amount of time in converting to ESM in the code base, or there is a larger pool of users requiring browser compatible code (which would require the library to be split up across the parts that are compatible with the browser and the rest). If on the other hand you want to do an example branch of the code with the changes then I am happy to review that and kick the tyres in how it would work in practice. |
Hi @peter-murray, I know you prefer node.js as primary use case for this lib and thats totally fine (my case is in some way special). I also could understand that converting to typescript is not what you want and in the end you should have joy building and maintaining this lib. Otherwise we all would suffer 😉 I'm totaly fine with a model.js in a dist folder. Thats right now the right way to do it I think. If you could provide a build with a separate Thanks for all the effort you invested here. |
There is a version of |
Great! I'll give it a try. In addition I would love to see the |
The problem is that the index.js is kind of locked in CJS and will be in CJS format until Node.js supports ESM natively, which is part of the problem you have with tree shaking. Lifting the I tried rollup, but unless you are writing in ESM module syntax, the results do not look like what you are after. This also results is a mess with TypeScript definitions not matching up unless you identically have the rollup modules exposed under |
The existing webpack stuff is on the master branch currently, just not the |
First commit in 5.0.0 alpha release to move the discovery out of the v3 API to remove some references that are not needed in the web app use case, f085599 It will take until release 6.x before I can complete the removal of all of this, but it is deprecated now. |
Thank you. Thats great news 😃 |
@KnisterPeter 👋 , I have just completed the extraction of the model to a pure TypeScript library that is used to provide CommonJS and ESM module systems (https://github.com/peter-murray/hue-bridge-model). I am preparing some changes to the way that this library will build, but other than the extraction of the library for the model, was there anything else here that was problematic to you? |
I would like to use this package as part of a client side library. This should (not tested it) right now, but its in some ways suboptimal.
The points I would address in this feature request:
bottleneck
is around 59k of code sizeget-ssl-certificate
is around 83k of code sizenode-mbed-dtls-client
is a native dependencydgram
is node specific and should be skipped for a browser bundleI could help to implement these and discuss solutions if this is accepted as target.
The text was updated successfully, but these errors were encountered: