This is a NodeCG boilerplate bundle, powered by React, Parcel and a Flux-like pattern system for an easy state-to-replicant management.
It works with NodeCG versions which satisfy this semver range: ^1.1.1
Copy/clone the repo into your bundles
folder that is located in the root folder of your NodeCG instance.
cd bundles
git clone git@github.com:mkrl/nodecg-react.git
cd nodecg-react
Install dependencies with yarn
or npm
yarn
# or
npm i
Start up your NodeCG instance.
In order to generate asset bundle from sources, run npm start
at least once, as the repository does not initially come with pre-compiled assets.
Parcel is a zero-configuration asset bundler. We use Babel to compile modern JavaScript with React into a single asset file that lives in our /graphics
folder.
In order to get started, run
npm start
This will spin up Parcel watch mode. Open your app through a NodeCG "graphics" tab. You can now make desired changes to your source files under /src
and they will automatically be hot-reloaded in your browser.
The main purpose of this bundle is to create a reliable bridge between replicants and React state using Flux-like store.
Let's say, we have a basic class-based root component (this is exactly what this bundle comes with):
...
class App extends React.Component {
constructor() {
super()
this.state = {
name: "Brandon"
}
}
render() {
return (
<div>
<h1>Hello, {this.state.name}!</h1>
</div>
)
}
}
...
Connecting to NodeCG replicants can then be done by importing replicate
from our stores/NodecgStore.js
. It is a function that takes a single argument - a replicant name.
After subscribing to a replicant, all you need to do is listen for changes on the store. At the very end our component should look something like this:
...
import NCGStore from './stores/NodecgStore'
import { replicate } from './stores/NodecgStore'
class App extends React.Component {
constructor() {
super()
this.state = {
replicants: NCGStore.getReplicants(),
}
}
componentDidMount() {
// Subscribing to replicant changes
replicate("name")
// We keep all our subscribed replicants in a single "replicants" object
NCGStore.on("change", () => {
this.setState({
replicants: NCGStore.getReplicants(),
})
})
}
render() {
return (
<div>
<h1>Hello, {this.state.replicants.name}!</h1>
</div>
)
}
}
...
Don't forget to define your replicants themselves, somewhere in your extension or a panel:
// extension.js
module.exports = nodecg => {
const nameReplicant = nodecg.Replicant('name', {defaultValue: "Brandon"})
}
Your component state will now be updated automatically whenever you initiate a replicant value change.
Bear in mind, if you don't declare your replicants before subscribing to them with replicate()
, their initial value will be set to undefined
, no matter what defaultValue
is being passed to the declaring statement.
Even though running in a watch mode does produce working pieces of code, you are going to need a production build after you are done with your development process. Generating optimized and minified graphics is as simple as:
npm run build
Feel free to contribute, following this conventional and simple process:
- Fork
- Create your feature branch (
git checkout -b new-cool-stuff
) - Commit (
git commit -am 'Add stuff'
) - Push to the branch (
git push origin new-cool-stuff
) - Create a new Pull Request
Please note that this is still an early work-in-progress.