Prerequisite: nwb must be installed globally (we're using version 0.18 in this guide):
npm install -g nwb
Quick development commands reduce the time between having a flash of inspiration and being able to develop and share it.
They are:
nwb react
for React codenwb inferno
for Inferno codenwb preact
for Preact codenwb web
for vanilla JavaScript code
They all have the same sub-commands:
run <entry.js>
runs a development serverbuild <entry.js> [dist/]
creates a production build
Say you have an idea for a Preact component and you whip up Lightbulb.js
:
import {h, Component} from 'preact'
export default class Lightbulb extends Component {
state = {
on: false
}
updateChecked = (e) => {
this.setState({on: e.target.checked})
}
render({wattage = 200}, {on}) {
return <div>
<label>
<input type="checkbox" checked={on} onClick={this.updateChecked}/>
{' '}
{wattage}W lightbulb is {on ? 'on' : 'off'}
</label>
</div>
}
}
To serve this for development use nwb preact run
, which will install essential dependencies, start a Webpack development server and automatically re-render when you make changes:
$ nwb preact run Lightbulb.js
✔ Installing preact
Starting Webpack compilation...
Compiled successfully in 3717 ms.
The app is running at http://localhost:3000/
To create a production build, use nwb preact build
:
$ nwb preact build Lightbulb.js
✔ Building Preact app
File size after gzip:
dist\app.b12334ec.js 8.63 KB
- Options for
run
andbuild
commands - Features
- Configuration
Specify a configuration file to use - see Configuration File.
Specify nwb plugins to use - see Style Preprocessing.
Don't use a rendering shim, run the provided entry module directly - see Opting out of Rendering Shims.
The default HTML template provided contains a <div>
which the app is rendered into, with a default id
of 'app'
. You can change the id
with this setting.
Contents for <title>
- defaults to the type of app you're serving, e.g. 'Preact App'
Use NpmInstallPlugin
to automatically install missing dependencies when an attempt is made to import them - see Automatic Dependency Installation.
Configures the host the development server will bind to.
Disables clearing the console before displaying Webpack compilation results - nwb clears the console by default to make it easier to read error messages without having to scroll back.
Disables the default fallback serving of index.html
for apps which make use of the HTML5 History API.
Port to run the dev server on (default: 3000
)
Automatically refresh the page when a Hot Module Replacement request was not accepted.
Note:
nwb web run
defaults this setting totrue
will reload the page by default on changes. To disable this, use a--no-reload
flag or use Webpack's Hot Module Replacement API in your app to accept module updates.
Enable extraction of modules imported from node_modules/
into a separate vendor
bundle.
These options only apply to
nwb react build
Create a build of a React project which uses Inferno or Preact as the runtime via a compatibility layer - see React Compatible Builds.
-
Write JavaScript with modern features and JSX, transpiled down to ES5.
-
Use new JavaScript feature proposals in the TC39 process:
- Class properties, for avoiding boilerplate when writing classes.
- Decorators.
- Export extensions.
-
Import images and stylesheets into JavaScript like any other module, to be handled by Webpack as part of its build.
import 'bootstrap/dist/css/bootstrap.css' <img src={require('./picture.jpg')}/>
-
Autoprefixed CSS, so you don't need to write browser prefixes.
-
Fallback serving of
index.html
at any URL so apps which use the HTML5 History API will work by default.
nwb has plugin modules which add Sass (nwb-sass
), Less (nwb-less
) and Stylus (nwb-stylus
) support without needing configuration.
To use them, pass a --plugins
option with an nwb plugin name (or a comma-separated list of names), with or without its nwb-
prefix.
e.g. to support importing Sass stylesheets, pass --plugins sass
and the necessary plugin will automatically be installed and used:
$ nwb preact run Lightbulb.js --plugins sass
✔ Installing nwb-sass
Starting Webpack compilation...
Having to stop and restart your development server to install new dependencies becomes a minor annoyance when you're in the middle of writing code.
If you pass an --install
flag to the run
command, nwb will configure NpmInstallPlugin
to automatically install missing dependencies when an attempt is made to import them.
$ nwb preact run Lightbulb.js --install
Starting Webpack compilation...
Now if we add the following to the top of Lightbulb.js
:
import 'bootstrap/dist/css/bootstrap.css'
Bootstrap will be installed and applied to the running app:
Recompiling...
Installing bootstrap...
Inferno and Preact both provide compatibility layers which simulate React APIs and patch up features which are different or missing compared to React, to allow them to run existing React code.
To try this out with some React code you've written, you can pass an --inferno
flag for a build which uses inferno-compat
or a --preact
flag for a build which uses preact/compat
.
If your code is compatible, these builds offer an easy way to take a large chunk off the size of the final bundle, and may even provide a performance boost.
$ nwb react build hello.js
✔ Building React app
File size after gzip:
dist\app.e718700a.js 46.5 KB
$ nwb react build hello.js --preact
✔ Installing preact
✔ Cleaning app
✔ Building Preact (React compat) app
File size after gzip:
dist\app.d786be80.js 12.86 KB
The inferno
and preact
commands are configured to use their respective compatibility layer for any React code which is imported - you'll only pay the cost of including the compatibility layer in your bundle if you import something which uses React.
e.g. if you want a live "time ago" component for your Inferno app, you can pull react-timeago
in:
import Inferno from 'inferno'
import TimeAgo from 'react-timeago'
let date = new Date()
export default function App() {
return <div>
This was rendered <TimeAgo date={date}/>
</div>
}
This section doesn't apply to the
nwb web
command, as you're in charge of rendering and using Hot Module Replacement in a vanilla JavaScript app.
Quick development commands can take care of the boilerplate for rendering and handling top-level Hot Module Replacement for React, Preact and Inferno.
Take advantage of this by writing the entry module you provide in the following ways:
You can export a component and it will be rendered:
import React from 'react'
export default class App extends React.Component {
render() {
return <div>
<h1>Idea!</h1>
</div>
}
}
You can directly export an Element (React terminology) or VNode (Inferno and Preact equivalent) and it will be rendered:
import Inferno from 'inferno'
export default <div>
<h1>Idea!</h1>
</div>
$ nwb inferno run idea.js
✔ Installing inferno, inferno-compat, inferno-clone-vnode, inferno-create-class and inferno-create-element
Starting Webpack compilation...
Compiled successfully in 3595 ms.
The app is running at http://localhost:3000/
If you're handling the initial render()
call yourself, you don't need to provide a target DOM node, as nwb hooks into the render()
method so it can keep handling top-level Hot Module Replacement for you.
nwb will use lack of exports from an entry module as indication that you're handling rendering yourself:
import React from 'react'
import {render} from 'react-dom'
class App extends React.Component {
render() {
return <h1>Hello world!</h1>
}
}
render(<App/>, document.getElementById('app'))
Hot Module Replacement (HMR) is a Webpack feature which enables patching code changes into a running app.
To support rendering when an entry module exports a Component, React Element or Inferno/Preact VNode, a rendering shim is used by default.
When the rendering shim detects that one of these has been exported from the provided entry module, it will handle the initial render and, where possible, will also accept HMR requests and handle re-render.
nwb react run
's configuration uses React Refresh Webpack Plugin to enable Fast Refresh for React components.
To disable this, pass a
--no-hmr
flag.
For other HMR scenarios, such as an exported React Element, nwb react run
's rendering shim will re-render to the same root DOM node.
If you don't want to use a rendering shim, pass a --force
flag the module you provide will be used as the entry point and you'll be responsible for rendering your app to the DOM.
You will also need to manually deal with HMR for Inferno and Preact if you want it, as they don't currently have Fast Refresh equivalents.
nwb supports configuration when you need it.
For quick tweaks, you can pass configuration arguments using dotted paths to set any of the documented configuration properties.
e.g. to enable CSS modules for imported .css
stylesheets:
$ nwb react run app.js --webpack.rules.css.modules
e.g. to use a Babel plugin which allows you to use class
and for
attributes in React JSX:
$ nwb react run app.js --babel.plugins=react-html-attrs
To make configuration tweaks permanent, you can put them in a configuration file.
nwb will automatically use an nwb.config.js
if present the working directory, or you can specify a custom file with a --config
option.