Preact Tutorial For Beginners

Table of Contents

What is Preact?

Preact is a JavaScript library that describes itself as a fast 3kB alternative to React with the same ES6 API. Preact tutorial for beginners from Coding compiler. Let’s start learning Preact and it’s features, components, how it is different from React and why you should switch from React to Preact. Let’s start learning Preact with code examples.

Preact – A library of a different kind

Preact – Closer to the action

Preact provides the smallest possible Virtual DOM abstraction on the DOM. The Web is a stable platform and it is time for us to re-implement it in the name of security.

Preact is also a flagship member of the web platform. It differentiates Virtual DOM against the DOM itself, registers real event handlers, and works hand in hand with other libraries.

Related Tutorial: Vuejs Tutorial

Preact – Smaller in Size

Most UI frameworks are so huge that they make up the bulk of a JavaScript app. It’s different with Preact: it’s tiny enough for your code to make up most of the application.

This means less JavaScript for downloading, analyzing and executing – the result is more time for your own code, so a self-determined experience without the struggle to keep a framework under control, is possible.

Preact – Great achievement

Preact is fast, not only because of its size. Thanks to a simple and predictable differentiation implementation, it is one of the fastest Virtual DOM libraries ever.

Preact even includes additional performance features such as customizable update batching, optional async rendering, DOM recycling, and optimized event handling using Linked State .

Preact – Portable & Easy to install

Preact’s tiny footprint allows the resource-rich Virtual DOM component paradigm to do things it might otherwise only dream of.

Use Preact to create parts of an app without complicated integration. Embed Bette Preact in a widget and apply the same tools and techniques that you would normally use in a full app.

Preact – Immediately Productive

Lightness is much funnier if you do not have to sacrifice productivity. Preacts makes you productive from the start! It even has some bonus features:

  • props, state and context are render()passed to
  • Standard HTML attributes (eg class and for) can be used
  • Works without any modification with React DevTools

Preact – Ecosystem Compatible

Virtual DOM components make it easy to reuse things – everything from the button to data sources. Preact’s design lets you use thousands of components already available in the React ecosystem.

Adding a simple preact-compat alias to the bundler adds a layer of compatibility that allows you to use even the most complex React components in your own Preact app.

Difference between Preact and React

Preact itself should not be a reimplementation of React. There are differences. Many of these differences are trivial or can be completely removed with the use of preact-compat . Preact-compat is a thin layer that overlays Preact and tries to be 100% compatible with React.

Preact is not designed to take on every single function of React to stay small and focused – otherwise it would make more sense to submit simple optimizations to the React project, which already has a very complex and well-designed code base.

Version compatibility

For Preact and preact-compat : Version compatibility is measured against the current and previous major releases of React. When new features are announced by the React team, they should be added to Preact’s core , should they be useful with the project goals in mind. This is a fairly democratic process, marked by constantly evolving discussions and decisions of the masses. He lives on issues and pull requests.

What is included?

  • ES6 Class Components
    • Classes provide an expressive way to define stateful components
  • High-Order Components
    • Components that render()emit other components of , effectively, are wrappers
  • Stateless Pure Functional Components
    • Functions that propsreceive as arguments and output JSX / VDOM
  • Contexts: Support for context was added in Preact 3.0.
    • Context is an experimental React function, but has been adopted by other libraries.
  • Refs: Support for function refs was added in Preact in 4.0. String refs are supported in preact-compat.
    • Refs provide a way to render rendered items and child components.
  • Virtual DOM Diffing
    • Quasi indispensable – Preact’s differentiation is simple, but effective and extremely fast .
  • h(), a more generalized version of React.createElement
  • This idea was originally called hyperscript and was valuable beyond the React ecosystem, so Preact advertises the original standard. ( Read: why h()? )
  • In addition, readable: h(‘a’, { href:’/’ }, h(‘span’, null, ‘Home’))

What is added in Preact?

Preact adds quite a few useful features inspired by the work of the React community.

  • This.props and this.state are render()passed on
    • You can still reference them manually. This procedure is simply cleaner, especially during destructuring
  • Stacked updates to the DOM setTimeout(1)returned and compared with (you can also use requestAnimationFrame)
  • You can easily use it class for CSS classes. className is still supported, class but is preferred.
  • Component and element reuse and pooling.

What is missing?

  • PropType Validation: Not everyone uses PropTypes, so they do not belong to Preact’s core.
    • PropTypes are fully supported by preact-compat , but can also be used manually.
  • Children : Not necessary in Preact because there is props.children always an array .
  • Synthetic Events: Preact’s goal in browser support does not require this additional overhead.
    • Preact uses the addEventListener browser native for event handling . Under Global event handler is to find a complete list of event handling DOM.
    • A full event implementation would mean more maintenance, lower performance, and a larger API.

What’s the difference between Preact and React?

Preact and React have some minute differences:

  • render() accepts a third argument, which is the base node to replace , otherwise it adds it. This could change a little in a future release, presumably by automatically detecting the appropriateness of a replacement renderer by examining the base node.
  • Implement components contextTypes or childContextTypes not. Children receive all context entries from getChildContext().

Types of Components in Preact

There two types of components in Preact:

  • Classical Components, with [lifecycle methods] and state
  • Stateless Functional Components, which are functions that accept props and return [JSX].

Within these two types, there are also a few different ways to implement components.

Example

Let’s use an example: a simple <Link> component that creates an HTML <a> element:

class Link extends Component {
   render(props, state) {
       return <a href={props.href}>{ props.children }</a>;
   }
}

We can instantiate/render this component as follows:

<Link href="https://example.com">Some Text</Link>

Destructure Props & State

Since this is ES6 / ES2015, we can further simplify our <Link> component by mapping keys from props (the first argument to render()) to local variables using destructuring:

class Link extends Component {
   render({ href, children }) {
       return <a {...{ href, children }} />;
   }
}

If we wanted to copy all of the props passed to our <Link> component onto the <a> element, we can use the spread operator:

 class Link extends Component {
   render(props) {
       return <a {...props} />;
   }
}

Stateless Functional Components

Lastly, we can see that this component does not hold state – we can render the component with the same props and get the same result each time. When this is the case, it’s often best to use a Stateless Functional Component. These are just functions that accept props as an argument, and return JSX.

const Link = ({ children, ...props }) => (
   <a {...props}>{ children }</a>
);

ES2015 Note: the above is an Arrow Function, and because we’ve used parens instead of braces for the function body, the value within the parens is automatically returned.

Getting Started with Preact

This tutorial shows how to create a simple ticking clock as a component. More detailed information on each topic can be found on the dedicated pages under the guidance menu.

You do not have to use ES2015 for Preact … but you should. This guide assumes that you have an ES2015 environment with Babel and / or Webpack / Browserify / Gulp / Grunt / etc. used. If not, use preact-boilerplate or a CodePen template .

Import what you need

The preact module offers the option for specific and general exports, so you can import everything under a personal namespace, or address the entire package.

Certainly:

import { h, render, Component } from 'preact';

// Ask Babel to transform JSX into h () calls:
/** @jsx h */

General:

import preact from 'preact';

//Tell Babel to transform JSX into preact.h () calls:
/** @jsx preact.h */

Certain imports work wonderfully with highly structured applications, but the general import is fast and never needs to be updated if you use different parts of the library.

Global Pragma

Instead of @jsx declaring the pragma in your own code you should prefer to .babelrc c onfigure it globally in a file.

Certainly:

With Babel 5 or lower:

 { "jsxPragma": "h" }

From Babel 6:

{
 "plugins": [
   ["transform-react-jsx", { "pragma":"h" }]
 ]
}

General:

For Babel 5 and lower:

{ "jsxPragma": "preact.h" }

From Babel 6:

{
 "plugins": [
   ["transform-react-jsx", { "pragma":"preact.h" }]
 ]
}

JSX Render

Preact provides a built-in h() functionality that converts JSX code into VDOM elements ( this is how it works ) . It also provides the render() function to create a virtual DOM DOM tree.

To render JSX, import these two functions and use them as follows:

import { h, render } from 'preact';

render((
   <div id="foo">
       <span>Hallo Welt!</span>
       <button onClick={ e => alert("hi!") }>Klick mich!</button>
   </div>
), document.body);

This should actually be known if you have already worked with hyperscript or one of its many friends .

Rendering Hyperscript in a Virtual DOM, however, makes no sense. Since you want to render components and update them when data changes, in this case the differentiation of the Virtual DOM really shines.

Components of Preact

Preact exports a generic component class, which can be extended to create encapsulated self-updating parts of a user interface. Components supports the standard React [life cycle methods] such as shouldComponentUpdate() and componentWillReceiveProps(). Providing specific implementations of these methods is the preferred way to control when and how components update.

In addition, components have a render() method, but it receives (props, state)arguments as opposed to React . This allows for an ergonomic approach that can be used to destruct props and state local variables that can then be referenced by JSX.

The following is a simple Uhr component that displays the current time.

import { h, render, Component } from 'preact';

class Uhr extends Component {
   render() {
       let time = new Date().toLocaleTimeString();
       return <span>{ time }</span>;
   }
}

// Eine Uhr-Instanz in <body> rendern:
render(<Uhr />, document.body);

So far so good. Running this statement generates the following HTML DOM structure ;:

<span>10:28:57 PM</span>

The component life cycle of Preact

In order for the clock to update every second, you need to know when <Uhr>to mount to the DOM. If you have already used HTML5 Custom Elements, you will find this familiar. It is similar with the attachedCallback- and detachedCallback- Lifecycle methods. If they are defined for a component, Preact calls the following lifecycle methods:

Lifecycle methodsWhenit is called
componentWillMountbefore the component is attached to the DOM
componentDidMountafter the component is attached to the DOM
componentWillUnmountbefore removing from the DOM
componentWillReceivePropsbefore new props are accepted
shouldComponentUpdatebefore render(). False spend to skip rendering
componentWillUpdatein front render()
componentDidUpdateto render()

Related Tutorial: VuePress Tutorial

So what you want is a one-second timer that starts as soon as the component is added to the DOM and stops as soon as it is removed from the DOM. This created timer is componentDidMount referenced and componentWillUnmount stopped by. Each time the timer statepasses, the component’s object is updated with a new time value. This automatically causes the component to be re-rendered.

import { h, render, Component } from 'preact';

class Uhr extends Component {
   constructor() {
       super();
       // Initiale Zeit einstellen:
       this.state.time = Date.now();
   }

   componentDidMount() {
       // Update time every second
       this.timer = setInterval(() => {
           this.setState({ time: Date.now() });
       }, 1000);
   }

   componentWillUnmount() {
       // Stop, if not renderable
       clearInterval(this.timer);
   }

   render(props, state) {
       let time = new Date(state.time).toLocaleTimeString();
       return <span>{ time }</span>;
   }
}

// Render an instance of clock in <body>:
render(<Uhr />, document.body);

How to Switch from React to Preact

There are two different ways to switch from React to Preact:

  1. To preact-compat install alias
  2. Modify the imports after preact changing and remove incompatible code

Simple: preact-compat Alias

Switching to Preact is actually very easy – you install preact-compat and set an alias for preact-compat instead of react and react-dom.

This allows one to continue writing React / ReactDOM code without having to make any changes to the workflow or the code base. Preact-compat Although adding about 2kb to the overall size of the project, it does have the advantage of supporting most of the existing React modules that should be found at npm .

In addition to Preact’s core, the preact-compat package provides all the changes needed to work exactly how react and react-dom in a single module.

The installation process is divided into two steps. First you have to install preactand preact-compat, two separate packages:

npm i -S preact preact-compat

Once these dependencies are installed, you must modify the build process so that React imports reference preact instead.

Related Tutorial: MobX Tutorial

How to Alias preact-compat

Now that the dependencies are installed, you have to configure the build process to forward any import from reactor react-dom to preact-compat.

Set the alias using webpack

Just add the following resolve.alias configuration to the webpack.config.js file:

{
 "resolve": {
   "alias": {
     "react": "preact-compat",
     "react-dom": "preact-compat"
   }
 }
}

Set the alias using Browserify

If Browserify is used, aliases can be defined by adding the aliasify transformation. This procedure works as follows:

You first install the transformation: npm i -D aliasify

And then assign aliasify to forwarding package.json to React imports preact-compat:

{
 "aliasify": {
   "aliases": {
     "react": "preact-compat",
     "react-dom": "preact-compat"
   }
 }
}

Manually setting the alias

Preact-compat Of course, if a build system is not used, or if a permanent switch is too desirable, you can also search for and replace all the import and prerequisites in the code base just as an alias would:

find: ([‘”])react(-dom)?\1

replace: $1preact-compat$1

However, in that case, preact switching to the full package instead of relying on it could be much more appealing preact-compat.

Preact’s core has a variety of features, allowing many idiomatic React codebases to be preactmoved directly with minimal effort .

Aliasing in Node using module-alias

Considering small-screen rendering capabilities, you can use the module-alias package to replace React with Preact, unless you use a bundler (such as Webpack) for the server-side code build process.

npm i -S module-alias

patchPreact.js:

var path = require('path')
var moduleAlias = require('module-alias')

moduleAlias.addAliases({
 'react': 'preact-compat/dist/preact-compat.min',
 'react-dom': 'preact-compat/dist/preact-compat.min',
 'create-react-class': path.resolve(__dirname, './create-preact-class')
})

create-preact-class.js:

import { createClass } from ‘preact-compat/dist/preact-compat.min’
export default createClass

If the new import syntax is used on your own Babel server, the above behavior will not work because Babel places all the imports at the top of a module. In this case, save the above code in a file called patchPreact.js and import it at the beginning of its file ( import ‘./patchPreact’). More about using module-alias can be found here .

It is also possible to set an alias directly using Node without relying on the module-alias packet. This method is based on internal properties of Node’s modular system, so you should enjoy it with care. To set an alias manually, the following steps are necessary:

// patchPreact.js
var React = require('react')
var ReactDOM = require('react-dom')
var ReactDOMServer = require('react-dom/server')
var CreateReactClass = require('create-react-class')
var Preact = require('preact-compat/dist/preact-compat.min')
var Module = module.constructor
Module._cache[require.resolve('react')].exports = Preact
Module._cache[require.resolve('react-dom')].exports = Preact
Module._cache[require.resolve('create-react-class')].exports.default = Preact.createClass

Create and Test

You are done – Now when you run the build process, all React imports will import instead preact-compat. The bundle is reduced so much. It’s always a good idea to run the test environment and the finished app to see if it really works.

Related Tutorial: Babel Tutorial


Optimal: Switch to Preact

The use of preact-compat in your own codebase is not required if you want to migrate from React to Preact. Preacts API is almost identical to Reacts API. Much of the React codebase can be migrated with miniscule or non-existent overhead.

In general, the process of switching to preact involves several steps:

1. Install Preact

This step is probably the simplest: you just have to install the library to use it!

npm install –save preact  # or: npm i -S preact

2. JSX Pragma: transpile to h()

Background: While the JSX language extension is independent of React, popular transpilers like Babel and Bublé use JSX to call conversion by default React.createElement().

There are historical reasons for this, but it is important to understand that the function that invokes JSX transpilations is an existing technology called Hyperscript . Preact pays homage to this and seeks to promote a better understanding of the simplicity of JSX by using it h()as its JSX Pragma .

TL; DR: React.createElement() is h()exchanged for the benefit of preact’s .

In JSX, the “pragma” is the name of a function that handles the creation of such an element:

<div /> transpilie to h('div')
<Foo /> transpilie to h(Foo)
<a href="/">Hallo</a> to h('a', { href:'/' }, 'Hallo')

In each of the above examples, h the function name is declared as JSX pragma.

With the help of Babel

If Babel is used, the JSX pragma can be defined in the .babelrc- or package.json-file. In which of the two files you do this is only dependent on personal preference:

{
 "plugins": [
   ["transform-react-jsx", { "pragma": "h" }]
 ]
}

Using comments

If you work with an online editor with Babel integration (eg JSFiddle or CodePen), you can define the JSX pragma by inserting a comment at the beginning of your code:

/** @jsx h */

With the help of Bublé

Bublé supports JSX by default. Jsx All you have to do is set the option:

buble({ jsx: 'h' })

3. Update legacy code

Although Preact strives for full API compatibility with React, small parts of the interface are intentionally not integrated. The most noticeable omitted part is createClass(). Class and OOP opinions vary widely, but it should be understood that JavaScript classes are internally represented in VDOM libraries to represent component types. This becomes important when working with the nuances of handling component life cycles.

If the codebase is heavily createClass() dependent on, there is still a great option: Laurence Dorman maintains a stand- alone createClass() implementation that works seamlessly in preact and is only a few hundred bytes in size. Alternatively, createClass() calls can be automatically converted to ES classes using Vu Trans preact-codemod .

Another noticeable difference is that Preact only supports feature references by default. String references are outdated in React and will be removed in the near future as they add a surprising amount of complexity for such minimal use.

If you want to continue to use string references in the future, this little feature provides a future-proof version that will this.refs.$$ continue to treat as string references. The simplicity of this small detour for function referencing also shows why functional referencing is now the preferred method.

4. Simplify root rendering

Since React 0.13, render() has been provided by the react-dom module. Preact does not use a separate module for DOM rendering, since it is focused solely on being a great DOM renderer. So, the last step in converting your codebase to Preact is switching ReactDOM.render() to preact’s render():

– ReactDOM.render(<App />, document.getElementById(‘app’));
+ render(<App />, document.body);

It should also be noted that Preacts render()feature is non-destructive, so rendering works well <body>and is even desirable.

This is possible because Preact does not expect to control the entire root element that you pass to Preact. The second render()argument is parent, which means it’s a DOM element being rendered into. If it is desired to re-render directly from the root (possibly for Hot Module Replacement), render()a replace element will accept as a third argument:

// initial render:
render(<App />, document.body);

// update in-place:
render(<App />, document.body, document.body.lastElementChild);

In the above example, one has to rely on the last child being the previously rendered root. Although this works in many cases (JSFiddles, CodePens, etc.), it is still better to have more control. Therefore, render()the root element returns: it passes it as the third argument to the Neurendern on.

The following example shows how to re-render Hot Module Replacement updates in response to webpacks:

// Root ist das Root DOM Element der App:
let root;

function init() {
 root = render(<App />, document.body, root);
}
init();

// Beispiel: Neurendern bei Webpack HMR-Aktualisierung:
if (module.hot) module.hot.accept('./app', init);

The complete process can be viewed at preact-boilerplate .

Preact API Reference

Preact.Component

Component is a base class that you will usually subclass to create stateful Preact components.

Component.render(props, state)

The render() function is required for all components. It can inspect the props and state of the component, and should return a Preact element or null.

import { Component } from 'preact';

class MyComponent extends Component {
   render(props, state) {
       // props === this.props
       // state === this.state

       return <h1>Hello, {props.name}!</h1>;
   }
}

Pract Lifecycle methods

Tip: If you’ve used HTML5 Custom Elements, this is similar to the attachedCallback and detachedCallback lifecycle methods.

Preact invokes the following lifecycle methods if they are defined for a Component:

Lifecycle methodWhen it gets called
componentWillMountbefore the component gets mounted to the DOM
componentDidMountafter the component gets mounted to the DOM
componentWillUnmountprior to removal from the DOM
componentWillReceivePropsbefore new props get accepted
shouldComponentUpdatebefore render(). Return false to skip render
componentWillUpdatebefore render()
componentDidUpdateafter render()

All of the lifecycle methods and their parameters are shown in the following example component:

import { Component } from 'preact';

class MyComponent extends Component {
   shouldComponentUpdate(nextProps, nextState) {}
   componentWillReceiveProps(nextProps, nextState) {
       this.props // Previous props
       this.state // Previous state
   }
   componentWillMount() {}
   componentDidMount() {}
   componentDidUpdate(prevProps, prevState) {}
   componentWillUnmount() {
       this.props // Current props
       this.state // Current state
   }
}

Preact.render()

render(component, containerNode, [replaceNode])

Render a Preact component into the containerNode DOM node. Returns a reference to the rendered DOM node.

If the optional replaceNode DOM node is provided and is a child of containerNode, Preact will update or replace that element using its diffing algorithm. Otherwise, Preact will append the rendered element to containerNode.

import { render } from 'preact';

// These examples show how render() behaves in a page with the following markup:
// <div id="container">
//   <h1>My App</h1>
// </div>

const container = document.getElementById('container');

render(MyComponent, container);
// Append MyComponent to container
//
// <div id="container">
//   <h1>My App</h1>
//   <MyComponent />
// </div>

const existingNode = container.querySelector('h1');

render(MyComponent, container, existingNode);
// Diff MyComponent against <h1>My App</h1>
//
// <div id="container">
//   <MyComponent />
// </div>

Preact.h() / Preact.createElement()

h(nodeName, attributes, [...children])

Returns a Preact Virtual DOM element with the given attributes.

All remaining arguments are collected into a children Array, and be any of the following:

  • Scalar values (string, number, boolean, null, undefined, etc)
  • More Virtual DOM elements
  • Infinitely nested Arrays of the above
import { h } from 'preact';

h('div', { id: 'foo' }, 'Hello!');
// <div id="foo">Hello!</div>

h('div', { id: 'foo' }, 'Hello', null, ['Preact!']);
// <div id="foo">Hello Preact!</div>

h(
   'div',
   { id: 'foo' },
   h('span', null, 'Hello!')
);
// <div id="foo"><span>Hello!</span></div>

Preact Forms

Forms in Preact work much the same as they do in React, except there is no support for the “static” (initial value) props/attributes. React Forms Docs

Controlled & Uncontrolled Components

React’s documentation on “Controlled” Components and “Uncontrolled” Components is immensely useful in understanding how to take HTML forms, which have bidirectional data flow, and make use of them from the context of a Component-based Virtual DOM renderer, which generally has unidirectional data flow.

Generally, you should try to use Controlled Components at all times. However, when building standalone Components or wrapping third-party UI libraries, it can still be useful to simply use your component as a mount point for non-preact functionality. In these cases, “Uncontrolled” Components are nicely suited to the task.

Related Tutorial: Rollup Tutorial

Checkboxes & Radio Buttons

Checkboxes and radio buttons (<input type=”checkbox|radio”>) can initially cause confusion when building controlled forms. This is because in an uncontrolled environment, we would typically allow the browser to “toggle” or “check” a checkbox or radio button for us, listening for a change event and reacting to the new value.

However, this technique does not transition well into a world view where the UI is always updated automatically in response to state and prop changes.

Walk-Through: Say we listen for a “change” event on a checkbox, which is fired when the checkbox is checked or unchecked by the user. In our change event handler, we set a value in state to the new value received from the checkbox. Doing so will trigger a re-render of our component, which will re-assign the value of the checkbox to the value from state. This is unnecessary, because we just asked the DOM for a value but then told it to render again with whatever value we wanted.

So, instead of listening for a change event we should listen for a click event, which is fired any time the user clicks on the checkbox or an associated <label>. Checkboxes just toggle between Boolean true and false, so clicking the checkbox or the label, we’ll just invert whatever value we have in state, triggering a re-render, setting the checkbox’s displayed value to the one we want.

Checkbox Example

class MyForm extends Component {
   toggle = e => {
       let checked = !this.state.checked;
       this.setState({ checked });
   };
   render({ }, { checked }) {
       return (
           <label>
               <input
                   type="checkbox"
                   checked={checked}
                   onClick={this.toggle} />
           </label>
       );
   }
}

Preact Linked State

One area Preact takes a little further than React is in optimizing state changes. A common pattern in ES2015 React code is to use Arrow functions within a render() method in order to update state in response to events. Creating functions enclosed in a scope on every render is inefficient and forces the garbage collector to do more work than is necessary.

Related Tutorial: Parcel Tutorial

External DOM Mutations

Sometimes there is a need to work with third-party libraries that expect to be able to freely mutate the DOM, persist state within it, or that have no component boundaries at all. There are many great UI toolkits or re-usable elements that operate this way. In Preact (and similarly in React), working with these types of libraries requires that you tell the Virtual DOM rendering/diffing algorithm that it shouldn’t try to undo any external DOM mutations performed within a given Component (or the DOM element it represents).

Technique

This can be as simple as defining a shouldComponentUpdate() method on your component, and having it return false:

class Block extends Component {
 shouldComponentUpdate() {
   return false;
 }
}

… or for shorthand:

class Block extends Component {
 shouldComponentUpdate = () => false;
}

With this lifecycle hook in place and telling Preact not to re-render the Component when changes occur up the VDOM tree, your Component now has a reference to its root DOM element that can be treated as static until the Component is unmounted. As with any component that reference is simply called this.base, and corresponds to the root JSX Element that was returned from render().

Unit Testing with Enzyme

React provides a react-addons-test-utils module for testing components, and Airbnb’s enzyme takes this concept further – incorporating multiple rendering modes and other useful features. Testing preact components using enzyme is possible thanks to the preact-compat-enzyme module, which implements the necessary internal React properties on top of preact-compat.

Enzyme Installation

We need two modules:

  • preact-compat-enzyme: to provide additional internal React properties.
  • preact-test-utils: to provide parts of the react-addons-test-utils API used by enzyme.
npm install --save-dev preact-compat-enzyme preact-test-utils

Configuration

Using Karma as a test runner, we’ll need to add some webpack aliases for React and a few other modules:

{
 "resolve": {
   "alias": {
     "react-dom/server": "preact-render-to-string",
     "react-dom/test-utils": "preact-test-utils",
     "react-dom": "preact-compat-enzyme",
     "react-test-renderer/shallow": "preact-test-utils",
     "react-test-renderer": "preact-test-utils",
     "react-addons-test-utils": "preact-test-utils",
     "react-addons-transition-group": "preact-transition-group",
     "react": "preact-compat-enzyme"
   }
 }
}

Current Limitations

  1. At present, only mount mode is supported.
  2. You may need to wrap assertions in a setTimeout when invoking the setProps() or setState() methods of React Wrapper.

Preact CLI

Preact CLI is the official build tool for Preact projects. It’s a single dependency command line tool that bundles your Preact code into a highly optimized Progressive Web App. It aims to make all of the above recommendations automatic, so you can focus on writing great Components.

Here are a few things Preact CLI bakes in:

  • Automatic, seamless code-splitting for your URL routes
  • Automatically generates and installs a ServiceWorker
  • Generates HTTP2/Push headers (or preload meta tags) based on the URL
  • Pre-rendering for a fast Time To First Paint
  • Conditionally loads polyfills if needed

Since Preact CLI is internally powered by Webpack, you can define a preact.config.js and customize the build process to suit your needs. Even if you customize things, you still get to take advantage of awesome defaults, and can update as new versions of preact-cli are released.

Progressive Web Apps using Preact

Preact is an excellent choice for Progressive Web Apps that wish to load and become interactive quickly. Preact CLI codifies this into an instant build tool that gives you a PWA with a 100 Lighthouse score right out of the box.

  • Loads less script – Preact’s small size is valuable when you have a tight loading performance budget.
  • A building block that works great with the React ecosystem – Whether you need to use React’s server-side rendering to get pixels on the screen quickly or use React Router for navigation, Preact works well with many libraries in the ecosystem.

Preact Performance Tips

While Preact is a drop-in that should work well for your PWA, it can also be used with a number of other tools and techniques. These include:

  • Code-splitting – breaks up your code so you only ship what the user needs for a page. Lazy-loading the rest as needed improves page load times.
  • Service Worker caching – allows you to offline cache static and dynamic resources in your app, enabling instant loading and faster interactivity on repeat visits.
  • PRPL – encourages preemptively pushing or pre-loading assets to the browser, speeding up the load of subsequent pages. It builds on code-splitting and SW caching.
  • Lighthouse – allows you to audit the performance and best practices of your Progressive Web App so you know how well your app performs.

Related JavaScript Tutorials For Beginners

JavaScript Introduction Tutorials

JavaScript Basics Tutorials

Leave a Comment