Use a js file in NodeJs and VueJs

Ok I finally found a way to use a js file both in the backend and frontend of a ui node. Not sure whether it is the best way to achieve it, but at least it seems to work. Will describe how to do it, in case anybody else ever needs it.

  1. For the ui-svg node in D2, I created following directory structure:

    node-red-dashboard-2-ui-svg
       nodes
          ui-svg.html
          ui-svg.js
       ui
          components
             UISvg.vue
          svg_utils.js
       vite.config.js
    
  2. The svg_utils.js is a commonJs file, containing the functions that I need in the backend and frontend:

    function addElement(document, svgElement, payload) {
     ...
    }
    function getSvg(svgElement, payload) {
       ...
    }
    function replaceSvg(svgElement, payload) {
     ...
    }
    
    module.exports = {
       addElement,
       getSvg,
       replaceSvg
    }
    
  3. This js file can be used in the backend ui-svg.js just like that:

    module.exports = function (RED) {
       const svgUtils = require('../ui/svg_utils.js')
       ....
       svgUtils.addElement(...)
    }
    

    As you can see in the debugger, all functions are available:

    image

  4. By default Vite will - during the build - only add npm packages (from the node_modules folder) into the bundle (.umd file), which you use in the vue file. So we need to specify in vite.config.js that our js file also needs to be transpiled from commonJs to an ESM module, and that this ESM module code needs to be included into the bundle file:

    import { resolve } from 'path'
    ....
    export default defineConfig({
        ...
        optimizeDeps: {
            include: ['ui/svg_utils.js']
        },
        build: {
            commonjsOptions: {
                 include: [/ui/, /node_modules/],
             },
            ...
         }
    })
    
  5. Now execute npm run build which will build everything and create our .umd bundle file.

  6. Finally use this transpiled ESM module from our sgv_utils.js file into our UISvg.vue file (i.e. the frontend code of the ui node):

    <template>...</template>
    
    <script>
       import * as svg_utils from '../svg_utils.js'
    
       export default {
          ...
         mounted () {
            this.$socket.on('msg-input:' + this.id, (msg) => {
               ...
               svg_utils.addElement(document, svg_drawing, payloadItem)
               ...
            }
         }
       }
    </script>
    

    And now in the debugger you can see that the same js file is available (in the bundle umd file) as an ESM module:

    image

So now - beside all imported npm modules - our custom js file is now also converted by Vite to an ESM module and included in the bundle.

Good luck coding UI nodes for D2!!
Bart

2 Likes