-
-
Notifications
You must be signed in to change notification settings - Fork 90
Using VueJS with Webpack
WORK IN PROGRESS The basics are correct but it would be better to use the VueJS simple example as the basis so that people can compare this to the non-build way of working.
Users of frameworks that normally use a build step to deploy code - such as WebPack - sometimes seem to struggle with using uibuilder. This page aims to explain a simple approach that works.
Before starting however, I should say that you don't need any of this unless you are creating a complex VueJS single page app. Check out the simple Vue example, that doesn't use a build step and it works fine, VueJS is far more efficient than Angular and a build step is much less critical. I've also built a more complex Vue-based home dashboard that receives large amounts of information every 30-60 seconds and it works well even on mobile devices - still no build step involved.
Also note that you should be able to adapt these instructions to other frameworks that also want a build stage. Please feel free to contribute other pages with instructions specific to other frameworks.
- Install the uibuilder node and the front-end framework you need. Here we will use VueJS as an example.
- Add an instance of the uibuilder node to your Node-RED flow along with any data you want to feed to it and any output processing. See the basic VueJS page of this WIKI for an example. Deploy the flow.
- You now have a folder containing the example source for your UI page. It is probably something like this:
~/.node-red/uibuilder
uibuilder
<instance-url>
dist
src
index.css
index.html
index.js
manifest.json
Where <instance-url>
matches the url you specified in the uibuilder node instance.
On a command line, navigate to the <instance-url>
folder then do the following@
npm init -y
npm --save install vue
npm install --save-dev webpack webpack-cli vue-loader vue-template-compiler vue-style-loader css-loader
If you want to, you can make vue
a dev-dependency too since the version that is used by uibuilder is installed in your ~/.node-red
userDir folder.
You may also wish to add other vue components such as vue-router
and bootstrap-vue
as desired.
Add the following to the package.json
file that has been created for you in the <instance-url>
folder:
"scripts": {
"build": "webpack --config ./webpack.config.dev.js"
},
'use strict'
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
mode: 'development',
entry: [
'./src/index.js'
],
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
}
]
},
plugins: [
new VueLoaderPlugin()
]
}
In the src
sub-folder, make sure you have the standard 3 index.(css|html|js)
files and add another called App.vue
<template>
<div>
<h1>Hello World!</h1>
</div>
</template>
Obviously, this is just a dummy. You will want to replace it with something meaningful.
This file will be included using your index.js
file and webpack will translate it into JavaScript via the vue-loader
plugin.
Alter the index.html
file like this:
<body>
<h1>OK Vue</h1>
<div id="app"></div>
<script src="/uibuilder/socket.io/socket.io.js"></script>
<!-- Note no leading / -->
<script src="./main.js" type="text/javascript"></script>
</body>
Keep the rest of the file the same.
Note that you are not including any of the "standard" JavaScript files now except for socket.io, they have all been packed into a single file. You can also include the Socket.IO client in your build if you like but there are some complexities, please look them up and deal with them rather than raising an issue with uibuilder.
This again is an absolutely bare minimum example of course.
// NOTE: If no path is given, webpack will look for installed modules
// If a path is given, it is relative to the folder containing this file
import Vue from 'vue'
import App from './App.vue'
// NOTE: Adjust the relative path (or use an absolute path) according to the acutal
// location of the uibuilderfe.js file
// In most installations, this will be 3 levels above the folder containing this file
import uibuilder from './../../../../node_modules/node-red-contrib-uibuilder/nodes/src/uibuilderfe.js'
new Vue({
el: '#app',
render: h => h(App),
mounted: function(){
console.debug('Vue:mounted - setting up uibuilder watchers')
console.log(uibuilder)
// Save confusion by keeping a specific reference to this Vue app
const vueApp = this
// If msg changes - msg is updated when a standard msg is received from Node-RED over Socket.IO
// Note that you can also listen for 'msgsReceived' as they are updated at the same time
// but newVal relates to the attribute being listened to.
uibuilder.onChange('msg', function(newVal){
console.debug('Vue:mounted:UIBUILDER: property msg changed! ', newVal)
}) // ---- End of uibuilder.onChange() watcher function ---- //
}, // --- End of mounted hook --- //
})
I will be trying to simplify the include for uibuilderfe.js in a future release.
Once again, this is a bare minimum example.
Now that you have everything available in the src
and root folders, you can (from the root folder) run npm run build
which will pack everything together and create dist/main.js
.
Finally, you need to copy your manifest.json
, index.html
and index.css
files from src
to dest
and then either redeploy your uibuilder node or restart Node-RED.
That last step makes the uibuilder instance switch from using the src
folder to using the dist
folder (something that I will improve in a future release of uibuilder). You only have to do that once.
Of course, you now need to remember to run the build step whenever you change a JavaScript or .vue file.
If you have any issues, firstly pare everything back to this minimal example so that you know you have the basics correct.
Then add complexity piece-by-piece until you find the issue. This example works so make sure you've followed the steps carefully.
You should end up with something like this:
~/.node-red/uibuilder/
uibuilder/
<instance-url>/
webpack.config.dev.js
package.json
node_modules/
dist/
index.css
index.html
main.js
manifest.json
src/
index.css
index.html
index.js
manifest.json
TBC
It isn't necessarily the best approach to have a single, very large js file with everything packed into it.
If the front-end libraries that you are using don't have any CSS or other assets that need to be loaded in your html page - such as images for example. Then you don't actually need to install the library into ~/node-red
as the standard instructions say.
There is no real harm in installing them - other than using up some disk space and resources - but any code won't be used since you are using webpack to pack all of the code into your dist/main.js
file.
I am far from being a webpack expert so I am certain there are better ways to do things. If you find a better way, please get in touch so that everyone can benefit.
Thanks, Julian.
Please feel free to add comments to the page (clearly mark with your initials & please add a commit msg so we know what has changed). You can contact me in the Discourse forum, or raise an issue here in GitHub! I will make sure all comments & suggestions are represented here.
-
Walkthrough 🔗 Getting started
-
In Progress and To Do 🔗 What's coming up for uibuilder?
-
Awesome uibuilder Examples, tutorials, templates and references.
-
How To
- How to send data when a client connects or reloads the page
- Send messages to a specific client
- Cache & Replay Messages
- Cache without a helper node
- Use webpack to optimise front-end libraries and code
- How to contribute & coding standards
- How to use NGINX as a proxy for Node-RED
- How to manage packages manually
- How to upload a file from the browser to Node-RED
-
Vanilla HTML/JavaScript examples
-
VueJS general hints, tips and examples
- Load Vue (v2 or v3) components without a build step (modern browsers only)
- How to use webpack with VueJS (or other frameworks)
- Awesome VueJS - Tips, info & libraries for working with Vue
- Components that work
-
VueJS v3 hints, tips and examples
-
VueJS v2 hints, tips and examples
- Dynamically load .vue files without a build step (Vue v2)
- Really Simple Example (Quote of the Day)
- Example charts using Chartkick, Chart.js, Google
- Example Gauge using vue-svg-gauge
- Example charts using ApexCharts
- Example chart using Vue-ECharts
- Example: debug messages using uibuilder & Vue
- Example: knob/gauge widget for uibuilder & Vue
- Example: Embedded video player using VideoJS
- Simple Button Acknowledgement Example Thanks to ringmybell
- Using Vue-Router without a build step Thanks to AFelix
- Vue Canvas Knob Component Thanks to Klaus Zerbe
-
Examples for other frameworks (check version before trying)
- Basic jQuery example - Updated for uibuilder v6.1
- ReactJS with no build - updated for uibuilder v5/6
-
Examples for other frameworks (may not work, out-of-date)
-
Outdated Pages (Historic only)
- v1 Examples (these need updating to uibuilder v2/v3/v4/v5)