# Using a client side JS file

**URL:** <https://discourse.nodered.org/t/using-a-client-side-js-file/47338>\
**Category:** Developing Nodes\
**Created:** [18 June 2021 14:33 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338 "2021-06-18T14:33:16Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [18 June 2021 14:33 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/1 "2021-06-18T14:33:17Z")

</div>

When building some custom nodes, I want to keep them separate in multiple files:  
custom1.js, custom1.html, custom2.js, custom2.html

However they share a lot of common functions in the editor (show/hide elements etc.)

How can I make use of my own JS file to make this available in the UI?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [18 June 2021 20:02 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/2 "2021-06-18T20:02:38Z")

</div>

If you have a look at the source code for node-red-contrib-uibuilder you will see some examples.

- `nodes/tilib.js` is a generic helper module that can be required.
- `nodes/uiblib.js` is more specific to uibuilder but is used in the same way.
- `nodes/socket.js` and `nodes/web.js` are both singleton class modules (only a single instance of the class can ever be created). This provides a great way to isolate code & data but ensure that multiple instances of a node always shared the same instance of the class. In this case, processing for [Socket.IO](http://Socket.IO) and ExpressJS respectively are encompassed by the modules & no matter how many uibuilder nodes you add to your flow, you will always share the same data.

---

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [19 June 2021 04:16 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/3 "2021-06-19T04:16:27Z")

</div>

Thank you for chipping in.

Sorry for not being clear:

I do know how to share JS files on server side implementation (had some fun commonJS vs. ES6 modules, which I would prefer).

What I was wondering:

How to share **client side** JavaScript functions. There's no obvious way how to do a `<script src=...></script>`

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [19 June 2021 08:04 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/4 "2021-06-19T08:04:03Z")

</div>

There are a few ways to achieve this but ultimately you have to serve the code via an endpoint.

Here is an example from one of my nodes - I like this pattern as I can share the `js` with both client and server side.

1. In your project, add folders `/static/`, `/static/js/` & `/static/css/`

2. Add a "dumb" node-red node called (for example) `app.js` - this is the end point that serves files from `/static/` to `http://xxxxx/image_tools/static/***`

3. Add the associated html file `app.html` - this dynamically loads your files at client side (via the end point created in `app.js`)

4. In package.json, add a node-red node pointing to `app.js`

5. create your shared js file. NOTE: in order to be able to import it both server and client side, you need to be a bit clever. This is the basics...

6. To use the js client side, you simple access `image_tools.getOptionsMap()`

7. To use the js server side, you require the file `const image_tools = require("./static/js/image_tools");`

I dont think i missed anything but if I did, have a look through the source of [node-red-contrib-image-tools](https://github.com/Steve-Mcl/node-red-contrib-image-tools) where I employ this solution.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [19 June 2021 09:15 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/5 "2021-06-19T09:15:08Z")

</div>

There is a much easier way of doing it since Node-RED 1.3.

Create a directory called `resources` at the top level of your node's module.

Any file under that directory will then be served up to the editor from the path `/resources/<module-name>/<filename>`

In your node html, add a script tag to load the file:

```auto
<script type="text/javascript" src="resources/your-module/your-file.js"></script>

```

Note there is no `/` at the start of the src path.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [19 June 2021 09:35 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/6 "2021-06-19T09:35:37Z")

</div>

> [@knolleary](#):
>
> There is a much easier way of doing it since Node-RED 1.3.

Ahh, nice. I was thinking something like automatic serving of resources would be a great feature - and it already exists 😳. Glad I didnt create a feature request now 🤣

Cheers Nick.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [19 June 2021 09:52 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/7 "2021-06-19T09:52:52Z")

</div>

Hi @Stwissel - so you should now have 2 solutions.

What I would like to say is if you intend on using this node only on new node-red installations (V1.3.x and above) then Nicks answer is the way to go. I would just like to add, if you do, it might be wise to specify the minimum node-red version in your package.json to avoid unnecessary bad feedback

```auto
    ...
    "node-red": {
        "version": ">=1.3.0",
        "nodes": {
            "mynode": "mynode.js"
        }
    },
    ...

```

  

However if your node is to be used by others who may be on earlier versions, you will have to DIY it with your own endpoint

@knolleary - please correct me if I am wrong on this point.

---

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [19 June 2021 17:30 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/8 "2021-06-19T17:30:35Z")

</div>

> [@Steve-Mcl](#):
>
> `version": ">=1.3.0",`

Awesome. My weekend project: fixing the Cloudant nodes

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [19 June 2021 17:42 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/9 "2021-06-19T17:42:58Z")

</div>

@Stwissel fixing them how?

Are you aware of the plan we had in place to update the cloudant nodes with Adam Hammond's cloudantplus set of nodes? The goal being to reduce how many forks we're out there?

> <https://github.com/node-red-contrib-ibm-cloud/community/issues/1>
>
> The original cloudant node is \[node-red-node-cf-cloudant\](https://github.com/lgf…a29/node-red-node-cf-cloudant) by @lgfa29. This is the node included in the Node-RED Starter App on IBM Cloud.
> 
> There have been a number of forks of the node, most notably \[node-red-contrib-cloudantplus\](https://flows.nodered.org/node/node-red-contrib-cloudantplus) maintained by @hammoaj
> 
> The cloudantplus node is actively maintained and has added a number of features over the original node. It has been (rightly) published with a different set of node types so it doesn't cause clashes if a user installs both nodes.
> 
> I have permission from @lgfa29 to take ownership of the npm module of the original node so we can publish updates to it.
> 
> I also have the support of @hammoaj who will be joining this community.
> 
> The tentative plan is:
> 
> 1. fork node-red-node-cf-cloudant into this organisation
> 2. merge the changes from cloudantplus into that repository
> 3. update the node types back to the original ones
> 4. publish a new version of the original node to npm.
> 5. update (with help from @lgfa29) the original cf-cloudant repository readme to mark it as deprecated and point to the repo in this organisation
> 6. update (with help from @hammoaj) the original cloudantplus repository to mark it as deprecated and point to the repo in this organisation
> 
> We \*may\* want to have a small period where updates are made to both the cf-cloudant repo and the original cloudantplus repo. This will allow updates to be made to both npm modules (with their different node types), to give users time to migrate back to cf-cloudant module.
> 
> That gets us to a clean baseline for the future development of the node.

It has stalled somewhat once I left IBM, but no reason for it not to get revived and the planned work completed.

---

<div class="post-metadata">

**Author:** ![Stwissel](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/stwissel/32/126_2.png) [@Stwissel](https://discourse.nodered.org/u/Stwissel)\
**Post date:** [19 June 2021 20:46 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/10 "2021-06-19T20:46:24Z")

</div>

Adam gave me the green light, signalling he would accept my pull request.  
Reworked it to use the newish IBM SDK. Also split the nodes into individual files  
for easier update. Made it work with IBM IAM....  
and put structure in place to addd mocha test (in GitHub Actions they run nicely since I can run CouchDB side container automatically). Still some work to go....

Sneak preview here:

> **[insectos/node-red-contrib-cloudantplus](https://github.com/insectos/node-red-contrib-cloudantplus)**
>
> Enhanced Cloudant node for Node-RED. Contribute to insectos/node-red-contrib-cloudantplus development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [18 August 2021 20:46 UTC](https://discourse.nodered.org/t/using-a-client-side-js-file/47338/11 "2021-08-18T20:46:29Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
