[Need Advice]: Loading resources by a node

Hi all,

I'm having a small issue with my nodes and would like your advice.

To avoid duplicating my code, I've separated some logic into two resources, and I'd like my nodes to load these resource before building themselves.

The first node to register loads both resources and everything is fine. But when the second node registers, it fails because the variable doesn't exist. Same with the third node.

Do you have any advices?

  • Resources
// The first one:
var FirestoreUI = FirestoreUI || (function () {
...
})();

// The second one:
var FirestoreQueryConstraintsContainer = FirestoreQueryConstraintsContainer || (function () {
... 
// use FirestoreUI
})();
  • First Node
<script type="text/javascript" src="resources/@gogovega/node-red-contrib-cloud-firestore/common.js"></script>
<script type="text/javascript" src="resources/@gogovega/node-red-contrib-cloud-firestore/constraints.js"></script>

<script type="text/javascript">
//Use FirestoreUI
...
</script>
  • Second and Third Node
<script type="text/javascript">
//Use FirestoreUI and FirestoreQueryConstraintsContainer 
...
</script>
  • Browser Console
ReferenceError: Can't find variable: FirestoreQueryConstraintsContainer
ReferenceError: Can't find variable: FirestoreQueryConstraintsContainer

Are these separate files?

If yes, do you add the resource script tag in all of the separate files?

Yes, three files

No, global variable should exist. The current version of my nodes declare these resource tags on each node file and it's work. But I think that the editor downloads the resources several times.

@GogoVega load your client script tags in a single html file and use defer to garantee execution order.

You can try keeping in separate files but you have to check if Node-RED guarantee idempotency when adding your node's html in the editor.

That is why you need nrg v3!

You mean the definition of the three nodes?

Yeah, It's a possibility. Initially, I didn't do it to maintain a certain readability.

No/yes. the browser takes care of that with its cache mechanism. The only time to really be concerned is if it runs some iife code. Otherwise, all good.

The script tags. Put them all in the same html file in order. And dont forget to add defer

Ok thanks a lot guys, I thought this was the wrong approach but... I'll leave it like this then.

I'll see for another day how I can build everything and put it in one file. (keeping the GH files separate)

If you look how vite/rollup do in framework like nuxt, you will see that having a single entrypoint html is the right way because they have to garantee the order js is executed to avoid reference errors like you have. They output an index.html with script tags in order, loaded in parallel, but executed in order using defer

But that means a build step and ton of crap dev deps (yuk)
For large projects, fine, but for simple node sets, no thank you.

EDIT:

Just to note, @AllanOricil I feel I should say, I am not knocking the great work you have done in support of the community

1 Like

You can configure common dependencies as external and add script tags from cdn. You can also bundle common dependencies in a single file and add it at the top of your .html. The second isnt good because it would take longer for the browser to download the file. We usually set chunking size using empirical values to reduce app loading time.

The best practices to make apps to load faster in the browser are:

  • chunking
  • minification
  • tree shaking

And you can't do any without a good bundler.

The same best practices apply for node-red because it serves a client app. However nobody cares about it YET! The more nodes you install that doesn't account for optmization in the client, the longer the browser will take to load all plugins and nodes.

I know. All good :+1: