# Uibuilder import data from local js file and export to it

**URL:** <https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851>\
**Category:** General\
**Tags:** uibuilder\
**Created:** [23 April 2023 16:49 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851 "2023-04-23T16:49:39Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![nerevar](https://avatars.discourse-cdn.com/v4/letter/n/f475e1/32.png) [@nerevar](https://discourse.nodered.org/u/nerevar)\
**Post date:** [23 April 2023 16:49 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/1 "2023-04-23T16:49:39Z")

</div>

Hello,

I want to make several (js) files in uibuilder to be imported when needed, and also to serve as a storage.

As I have no idea how to import and use a js file, I've tried this:

in `src/views/overview.vue`  
in data: `test: {},`  
in created:

```auto
const test = require('../resources/test.js');
this.test = {test};

console.log('testis: ', this.test.testis);
console.log('test objekt: ', (JSON.stringify(this.test)));

```

`test.js` has the following content:

```auto
const data = {
    test: {
      testis: 5
    }
  };
  
module.exports = data;

```

the data items is always empty, no matter I get it in created or beforeCreate, or I get console.log in monted

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [23 April 2023 18:49 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/2 "2023-04-23T18:49:40Z")

</div>

have you defined your main `index.js` file as type **module**?

```auto
...
    <script defer src="../uibuilder/uibuilder.iife.min.js"></script>
    <script defer type="module" src="./index.js"></script>
...

```

`test.js` can be

```auto
export const data = {
    test: {
      testis: 5
    }
  };

```

and in the .vue file you can use `import { data } from "../resources/test.js"`

and try to `console.log(data)` in Vue lifecycle hook `created`

ps. how are you loading those .vue files .. are you using some bandler like vite ?

---

<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:** [23 April 2023 18:58 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/3 "2023-04-23T18:58:33Z")

</div>

Remember the difference between what happens in Node-RED (a node.js server app that supports require and import) and the front-end (your index.html, index.js, etc where require is not supported at all and import is only supported in HMTL ES Modules so you have to use the ESM version of the client library).

As Andy helpfully points out, you simply create another .js file in the same folder as index.js and then load it using a script tag as he has shown the index.js file being loaded.

However, to us a .vue file directly, you must either "build" them into a .js file or load them dynamcially using something like the http-vue-loader library. Examples in the uibuilder WIKI.

[Home · TotallyInformation/node-red-contrib-uibuilder Wiki (github.com)](https://github.com/TotallyInformation/node-red-contrib-uibuilder/wiki)

---

<div class="post-metadata">

**Author:** ![nerevar](https://avatars.discourse-cdn.com/v4/letter/n/f475e1/32.png) [@nerevar](https://discourse.nodered.org/u/nerevar)\
**Post date:** [23 April 2023 20:48 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/4 "2023-04-23T20:48:00Z")

</div>

> [@UnborN](#):
>
> have you defined your main `index.js` file as type **module**?
> 
> ```auto
> 
> ```

No, I cant load the vue files with httpVueLoader then

> [@UnborN](#):
>
> and in the .vue file you can use `import { data } from "../resources/test.js"`

I'm getting errors if I do that:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/3/43985f557eaab99cdf975267ebd4a9a524b6d416.png)

> [@UnborN](#):
>
> ps. how are you loading those .vue files .. are you using some bandler like vite ?

I'm using httpVueLoader

---

<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:** [23 April 2023 21:36 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/5 "2023-04-23T21:36:40Z")

</div>

> [@nerevar](#):
>
> No, I cant load the vue files with httpVueLoader then

Try [FranckFreiburger/vue3-sfc-loader: Single File Component loader for Vue2 and Vue3. Load .vue files directly from your HTML. No node.js environment, no build step. (github.com)](https://github.com/FranckFreiburger/vue3-sfc-loader) instead. That works with Vue 2 & 3.

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [23 April 2023 21:45 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/6 "2023-04-23T21:45:17Z")

</div>

> [@nerevar](#):
>
> I cant load the vue files with httpVueLoader then

yes .. i remember having some issue too when i first tried out httpVueLoader  
either use Julian's link for the vue3-sfc-loader  
or use a bundler like [Vite](https://vitejs.dev/)

I have a sample template Github repo of a simple navigation bar using Vue2, bootstrap-vue and vue-router if you want to browse through the code and test. it uses vite to build the app  
**[uib-template-vue-navbar](https://github.com/unborn-andy/uib-template-vue-navbar)**

---

<div class="post-metadata">

**Author:** ![nerevar](https://avatars.discourse-cdn.com/v4/letter/n/f475e1/32.png) [@nerevar](https://discourse.nodered.org/u/nerevar)\
**Post date:** [24 April 2023 04:14 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/7 "2023-04-24T04:14:17Z")

</div>

Ok, ty. I will try.

This is actualy my first true use of uibuilder, thats why i'm having all sorts of questions. It will be pretty comprehensive too, with loads of dynamic css moving png around and over the bottom layered svgs. Charts and tables will be inside svgs as you click them. Over svg also need to be gauge charts. I'm not sure how will it all behave after its been completed, so maybe I'll have to build it after all

---

<div class="post-metadata">

**Author:** ![nerevar](https://avatars.discourse-cdn.com/v4/letter/n/f475e1/32.png) [@nerevar](https://discourse.nodered.org/u/nerevar)\
**Post date:** [24 April 2023 10:38 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/8 "2023-04-24T10:38:18Z")

</div>

> [@TotallyInformation](#):
>
> > [@nerevar](#):
> >
> > No, I cant load the vue files with httpVueLoader then
> 
> Try [FranckFreiburger/vue3-sfc-loader: Single File Component loader for Vue2 and Vue3. Load .vue files directly from your HTML. No node.js environment, no build step. (github.com)](https://github.com/FranckFreiburger/vue3-sfc-loader) instead. That works with Vue 2 & 3.

Why it's everything so hard?

I've been trying to get it running for 2 hors now.

errors from the first example (the page doesnt even load):

> <https://github.com/FranckFreiburger/vue3-sfc-loader/blob/main/docs/examples.md#vue2-basic-example>

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/0/d0b2d17292d5f2a224de0c20987f9f9bcb7b0e11.png)

  
  

Errors from the second example (only 1 and a half component loaded):

> <https://github.com/FranckFreiburger/vue3-sfc-loader/issues/38#issuecomment-1060326961>
>
> I can't seem to figure out how to use the vue2-sfc-loader. If I simply include \`…https://cdn.jsdelivr.net/npm/vue3-sfc-loader/dist/vue2-sfc-loader.js\`, nothing seems to get added to the \`window\` object, so code like
> 
> \`\`\`javascript
> const { loadModule } = window\['vue3-sfc-loader'\];
> \`\`\`
> 
> or
> 
> \`\`\`javascript
> const { loadModule } = window\['vue2-sfc-loader'\];
> \`\`\`
> 
> just fails. Does the Vue 2 version work different from the Vue 3 version somehow? Unfortunately there are no example for the Vue 2 version, and I really don't want to dig through the minified source to try and find out how this is supposed to work, so it would be good if you could provide an example of how the Vue 2 version is supposed to be used.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/c/bcfc3d2acaa86e2c5f6d5bab293cb255abb87fb6.png)  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/8/18a7720c0caa549b376fd3f64612f89e3004a0e3.png)

This is the code for declaring components:

```auto
const Navbar = Vue.component('Navbar', () => loadModule('./components/Navbar.vue', options));
const Overview = Vue.component('Overview', () => loadModule('./views/Overview.vue', options));
....
const routeDefs = [
    {
        path: '/',
        component: Overview
    },{
        path: '/glueline',
        component: GlueLine
    },{
        path: '/Settings',
        component: Settings
    }
]

const app = new Vue({

    el: '#app',
    router: new VueRouter({routes: routeDefs}),
    components: {
        Navbar,

```

I just dont understand....

P.S. everything worked OK with httpVueLoader, but I cant import JS and export to it

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [24 April 2023 17:17 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/9 "2023-04-24T17:17:22Z")

</div>

Do you have your full code on Github so we can test this ?

---

<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:** [24 April 2023 21:34 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/10 "2023-04-24T21:34:38Z")

</div>

> [@nerevar](#):
>
> Why it's everything so hard?

One of the reasons I no longer use any frameworks.

* * *

Here is some code that should work I think. Though I think that it is using Vue v3 so if you have Vue v2 installed, switch the vue library script line to the commented out version to load from CDN to save you messing about.

index.html

```auto
<!doctype html>
<html lang="en"><head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Simple Vue3 with new uib client - Node-RED uibuilder</title>
    <meta name="description" content="Node-RED uibuilder - Simple Vue3 with new uib client">
    <link rel="icon" href="./images/node-blue.ico">

    <!-- Your own CSS -->
    <link type="text/css" rel="stylesheet" href="./index.css" media="all">

    <!-- #region Supporting Scripts. These MUST be in the right order. Note no leading / - socket.io no longer needed -->
    <!-- <script defer src="https://cdn.jsdelivr.net/npm/vue@latest/dist/vue.global.prod.js">/* Remove .prod for development version */</script> -->
    <script defer src="../uibuilder/vendor/vue/dist/vue.global.prod.js">/* Remove .prod for development version */</script>
    <script defer src="../uibuilder/vendor/vue3-sfc-loader/dist/vue3-sfc-loader.js"></script>
    <script defer src="../uibuilder/uibuilder.iife.min.js"></script>
    <script defer src="./index.js">/* OPTIONAL: Put your custom code in that */</script>
    <!-- #endregion -->

</head><body class="uib">

    <div id="app">
        <h1>Simple Vue v3 App Using New uibuilder IIFE Client - v6.1.0</h1>

        <p>{{ message }}</p>

        <div id="more"><!-- '#more' is used as a parent for dynamic content in examples --></div>

        <div style="border:2px solid silver;">
            <my-component color="yellow"></my-component>
        </div>

        <p>
            <button @click="count++" title="Not sent back to Node-RED - this just shows that VueJS is working">
                Simple VueJS Counter: {{ count }}
            </button>
        </p>
        
        <p>
            <button @click="doEvent" data-mything="This is a thing" title="This is sent back to Node-RED">
                Click to send msg to Node-RED
            </button>
        </p>
        
        <p>
            <label for="input1">This is sent to Node-RED when you exit it: </label>
            <input v-model="input1" @change="doInputChange" id="input1" type="text" placeholder="Type text then exit field">
        </p>
        
        <pre id="msg" v-html="formatLastRcvd" class="syntax-highlight">Waiting for a message from Node-RED</pre>
    </div>

</body></html>

```

index.js

```auto
// @ts-nocheck
'use strict'

const { createApp } = Vue
const { loadModule } = window["vue3-sfc-loader"]

// See vue3-sfc-loader docs for details.
const sfcOptions = {

    moduleCache: {
        vue: Vue,
    },

    getFile(url) {
        return fetch(url).then(response => response.ok ? response.text() : Promise.reject(response));
    },

    addStyle(styleStr) {
        const style = document.createElement('style');
        style.textContent = styleStr;
        const ref = document.head.getElementsByTagName('style')[0] || null;
        document.head.insertBefore(style, ref);
    },

    log(type, ...args) {
        console.log(type, ...args);
    }
}

// Using the Vue options API style for beginner simplicity
// No need to pre-define Quasar's $q when working with the options API
const app = createApp({
    components: {
        'my-component': Vue.defineAsyncComponent(() => loadModule('./myComponent.vue', sfcOptions)),
    },

    // Define Vue reactive variables
    data() {
        return {

            message: 'Hello Vue!',
            count: 0,
            lastMsgRecvd: '[Nothing]',
            input1: '',

        }
    },

    // Dynamic data
    computed: {

        // This is auto-recalculated by Vue when lastMsgRecvd changes
        formatLastRcvd() {
            const lastMsgRecvd = this.lastMsgRecvd
            if (typeof lastMsgRecvd === 'string') return 'Last Message Received = ' + lastMsgRecvd
            return 'Last Message Received = ' + uibuilder.syntaxHighlight(lastMsgRecvd)
        },

    },

    // Supporting functions
    methods: {

        // Use the uib helper function to send something to NR
        doEvent(event) { uibuilder.eventSend(event) },

        /** Runs when the change event for the source field is fired
         * @param {InputEvent} event The event object is passed by the browser automatically
         */
        doInputChange(event) {
            console.log('input1 text has changed: ', event.target.value)
            // Send the new text to Node-RED
            uibuilder.send({
                'topic': 'input1-changed',
                'payload': event.target.value,
            })
        },

    },

    // Lifecycle hooks
    mounted() {
        // If msg changes - msg is updated when a standard msg is received from Node-RED
        uibuilder.onChange('msg', (msg) => {
            console.log('>> msg recvd >>', msg, this)
            this.lastMsgRecvd = msg
        })
    },
})

app.mount('#app')

```

myComponent.vue

```auto
<template>
    <div>
        <p>
            The VueJS component called <a href="https://github.com/FranckFreiburger/vue3-sfc-loader" target="_blank">vue3-sfc-loader</a>
            provides the ability to dynamically load a Vue component from a <code>.vue</code> file without the need for a pre-build step.
        </p>
        <P>
            It is worth noting that this also works with VueJS v2. 
            See the <a href="https://github.com/FranckFreiburger/vue3-sfc-loader/blob/main/docs/examples.md#vue2-basic-example" target="_blank">docs</a> for details.
        </P>
        <p>
            This example uses a dynamically loaded <span class="example">{{ msg }}</span> file!
        </p>
    </div>
</template>

<style scoped>
    .example {
        color: v-bind('color');
    }
    p::before {
        content: "VUE file content: ";
        font-variant-caps: small-caps;
        font-style: italic;
    }
</style>

<script>
    export default {
        data() {
            return {
                msg: 'myComponent.vue',
                color: 'red',
            }
        }
    }
</script>

```

---

<div class="post-metadata">

**Author:** ![nerevar](https://avatars.discourse-cdn.com/v4/letter/n/f475e1/32.png) [@nerevar](https://discourse.nodered.org/u/nerevar)\
**Post date:** [25 April 2023 06:43 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/11 "2023-04-25T06:43:08Z")

</div>

> [@UnborN](#):
>
> Do you have your full code on Github so we can test this ?

It's not mine. Yet

> [@TotallyInformation](#):
>
> Here is some code that should work I think. Though I think that it is using Vue v3 so if you have Vue v2 installed, switch the vue library script line to the commented out version to load from CDN to save you messing about.

  
Ok, it's working. However, there are some minor warnings:

```auto
vue.global.js:1661 [Vue warn]: Template compilation error: v-html will override element children.
27 | </p>
28 |          
29 | <pre id="msg" v-html="formatLastRcvd" class="syntax-highlight">Waiting for a message from Node-RED</pre>
   | ^^^^^^^^^^^^^^^^^^^^^^^
30 |       
  at <App>

vue.global.js:1661 [Vue warn]: Failed to resolve component: P
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <Anonymous color="yellow" > 
  at <AsyncComponentWrapper color="yellow" > 
  at <App>

```

  
Not sure If I want to go with it though. In my tests I've found comments sometimes throws warnings, also, the imported component css doesn't load local images... Plus, I'ts way slower and not sure if it's suited for a great number of components, as it loaded them much slower (maybe I used the cdn version, not local):

```auto
const Navbar = httpVueLoader('./components/Navbar.vue');
const GlueLine = httpVueLoader('./views/GlueLine.vue');
const Overview = httpVueLoader('./views/Overview.vue');
const Settings = httpVueLoader('./views/Settings.vue');
/*const test1 = httpVueLoader('./tests/test1.vue');
const star1 = httpVueLoader('./tests/star1.vue');
const test2 = httpVueLoader('./tests/test2.vue');
const test3 = httpVueLoader('./tests/test3.vue');
const test4 = httpVueLoader('./tests/test4.vue');
const alphaLj1 = httpVueLoader('./tests/alphaLj1.vue');*/
const svgLoader = httpVueLoader('./svgs/svgLoader.vue');
//const g9320 = httpVueLoader('./tests/g9320.vue');
const svgLj1 = httpVueLoader('./svgs/p2_lj1.vue');
const svgLj2 = httpVueLoader('./svgs/p2_lj2.vue');
const svgLj3 = httpVueLoader('./svgs/p2_lj3.vue');
const svgPak1 = httpVueLoader('./svgs/p2_pak1.vue');
const svgPak2 = httpVueLoader('./svgs/p2_pak2.vue');
const svgPak3 = httpVueLoader('./svgs/p2_pak3.vue');
const svgTop = httpVueLoader('./svgs/p2_top.vue');
const svgTrans = httpVueLoader('./svgs/p2_transp.vue');
const svgTric = httpVueLoader('./svgs/p2_tric.vue');

```

  
Too much bother to just load some objects from a js file - in the meantime I loaded the data I needed externaly from the Node-RED. 

Thx for the effort though

---

<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:** [25 April 2023 09:16 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/12 "2023-04-25T09:16:12Z")

</div>

> [@nerevar](#):
>
> However, there are some minor warnings

Never said it was perfect 😁

> [@nerevar](#):
>
> css doesn't load local images

Not sure what you mean by that. Any images in CSS are the same as in your HTML, they need to come from the server - uibuilder in this case.

> [@nerevar](#):
>
> Plus, I'ts way slower and not sure if it's suited for a great number of components, as it loaded them much slower

Yes, that is to be expected. As you say, it is designed for small apps not big ones. If you are doing a big Vue app, same as any other framework, you should use a build step to "compile" everything. That will always be way more efficient in use.

> [@nerevar](#):
>
> in the meantime I loaded the data I needed externaly from the Node-RED.

Yup. I mentioned that I'm no longer using any frameworks. uibuilder on its own with Node-RED does pretty much everything I was doing with frameworks before - just using vanilla HTML/CSS - I'm hardly ever even using front-end JavaScript either now.

If I really needed something complex, I might use Svelte to lend a hand but even there, I would probably just use `uib-element` instead with some additional tweaks using the low-code config to create some HTML, copy that HTML and save to the index.html file so it wasn't being dynamically created each time and then use `uib-update` (or the low-code config directly) to update things as needed.

Probably wouldn't scale to enterprise-grade usage with many 100's of users but for a lot of things, it is more than enough.

---

<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:** [24 June 2023 09:16 UTC](https://discourse.nodered.org/t/uibuilder-import-data-from-local-js-file-and-export-to-it/77851/13 "2023-06-24T09:16:18Z")

</div>

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