React ES6 and pre-ES6 components, built with Babel, Npm and Webpack
React is a JavaScript library designed to create UI (User Interface) components. However, because React is small and excels at what it does, it's inevitably used with hundreds -- perhaps even thousands -- of other JavaScript libraries and frameworks. Therefore seeing project spin-offs named React-<blank> or writings titled React with <blank> has become the norm rather than the exception. What you'll read next is exclusively centered on React with the only assumption being you're familiar with some of JavaScript's earliest concepts like events, DOM & jQuery -- reading the previous section What is JavaScript ? What is modern JavaScript ? should be enough to get you through this React tutorial.
React is small, but it does have its own particular syntax, development and deployment process, which is why it can feel overwhelming on many fronts to new users. Because of this, I'll start with a jQuery example explained previously and create equivalent React examples so you have a basis for comparison. The following example illustrates this jQuery web page that uses a couple of events linked to a button and an AJAX call.
React components are relatively easy to understand, but what steepens React's learning curve is there are multiple ways to develop React components, as well as multiple ways to deploy React. React started prior to ES6, which was a major JavaScript milestone version that introduced simpler syntax to work with OOP (Object Orientated Programming) classes, objects and inheritance. Because ES6 is still not mainstream, React components continue to support their old ad-hoc class syntax, as well as a newer ES6 class syntax. In addition, React components use a markup language called JSX that must be converted to plain JavaScript, which in turn creates multiple deployment alternatives. So React concepts account for at most 30% of the learning curve, while the remaining 70% consists of learning different React syntax and tools required to deploy React.
In the first part of this tutorial, I'll stick to exploring React component concepts and syntax, using the simplest deployment alternative which consists of browsers doing pre-processing & downloading multiple libraries to run React components. In the second part and once you get a feel for React itself, I'll discuss how to pre-process and bundle React using two of the most popular modern JavaScript tools: npm & webpack.
Part I: React component concepts, with and without ES6
The following examples represent equivalent React web pages of the previous jQuery example. Both React examples produce the same result, except one uses React's ad-hoc class syntax and the other React's ES6 class syntax.
JSX, <script type="text/babel">, babel and transpiling
If you skim through either main index.html
page in the previous React examples, you can see the overall web page structure isn't very different from non-React web pages. That is, there are <script>
elements to import resources, a <head>
and <body>
element, as well as standard HTML elements like <div>
, <h4>
and <button>
. However, although the inline JavaScript is wrapped in a regular <script>
element, notice it uses the type="text/babel"
attribute.
React uses a JavaScript-like syntax named JSX to make it easier to declare components. You don't have to use JSX, but using JSX will definitely make it more enjoyable to work with React. To give you an idea, the following snippet shows the React components from the previous examples with inline JSX and its equivalent plain JavaScript.
React component with inline JSX and equivalent JavaScript transpiled from JSX
|
|
The key piece of syntax is the return
value of the render()
method. Both left-hand side versions return a JSX snippet which you can see has a more markup feel to it, like a lot of UI syntax (e.g. HTML, XML). On the other hand, the right-hand side has a more programmatic feel to it being plain JavaScript. If you think you would be more comfortable writing something like the right-hand side (i.e. plain JavaScript) instead of either left-hand side version (i.e. JSX), congratulations, you can skip to the next section and never hear from JSX again. If you're like most of us though, you'll come to rely on JSX to use React.
As helpful and friendly as JSX is to define JavaScript components, it's not JavaScript, but rather a language that produces JavaScript. This means that in order for browsers to interpret JSX, JSX needs to be converted to plain JavaScript, which is where the text/babel
attribute for the <script>
tag used in both examples comes into play.
Near the top of both index.html
web pages you can see we import babel-core/5.8.24/browser.js
. This library is tasked with looking for <script type="text/babel">
tags and transforming their contents from JSX to plain JavaScript.
This transformation process known as transpiling -- described earlier as part of Modern JavaScript essentials -- is done directly on a user's browser through the babel library in both these examples. However, be aware that performing the transpilation process on a user's browser and sending the babel library over a network for this purpose, should only be done in limited circumstances like these examples.
For real life applications, the transpilation process for JSX should be done as part of the deployment process, so end users receive plain JavaScript in their browsers. This in turn speeds up the web page, since it reduces the work needed to be done by a browser and also reduces the amount of ancillary downloads required for the transpilation process. The second half of our React discussion describes how to integrate transpilation as part of the deployment process. Next, I'll continue discussing these same examples that rely on an end user's browser doing the transpilation process.
Render React components on web pages
React components are rendered on web pages by appending them to standard HTML elements, similar to how you append HTML nodes on web pages with jQuery or standard DOM. The following snippet illustrates the relevant parts to render a React component, taken from the index.html
web page in the previous examples.
Render React component to web page
|
In this snippet you can see the standard HTML element <div id="banner-container"></div>
that's used to append a React component. Next, in the <script>
section is a call to ReactDOM.render()
which takes two arguments. The first ReactDOM.render()
argument is the React component you want to render, in this case <BannerContainer>
with the message="React 101!"
attribute. The second ReactDOM.render()
argument is the HTML element on which you want to append the React component, in this case we use the standard DOM document.getElementById()
method to reference the HTML element with id="banner-container"
.
And that's all there is to rendering a React component on a web page. If you want to render the same React component on multiple HTML elements you can broaden the matching pattern, just as you can use the ReactDOM.render()
statement multiple times to render different React components.
Next, our focus will shift to the actual structure of a React component. As I mentioned at the start, there are two ways to develop React components. I'll first describe React's ad-hoc pre-ES6 class syntax and later describe React's ES6 class syntax. Both techniques produce the same results, so the next two sections are complementary to one another.
React components with ad-hoc class syntax (pre-ES6)
A React component can be created using React'sReact.createClass()
method. Inside the React.createClass()
, you can declare React's life-cycle methods, custom methods, as well as the actual HTML the component generates. The general idea of a React component is to encapsulate all actions and markup in the same place, unlike it's done in something like jQuery where HTML and JavaScript are declared separately. The following listing illustrates the structure of the <BannerContainer>
component used in the example that uses ad-hoc React class syntax.
React component structure with createClass()
|
The method you'll end up using most in React components -- which is a requirement -- is the render()
method which defines the HTML for the component. This means that whenever you render the <BannerContainer>
component from this snippet, React outputs the HTML <div><h4>.....</h4></div>
.
In addition, in this component there are two types of React component methods: life-cycle methods that are invoked automatically and custom methods that need to be manually hooked-up to triggers. The render()
method is a life-cycle method that outputs the component's HTML and the getInitialState()
method is another life-cycle method that initializes a React component's state. The handleClick
and handleAjaxButtonClick
methods are custom methods that need to be hooked up to triggers (e.g.click, hover) as part of the HTML in the render()
method.
In React components you can use the this
keyword to reference the current instance of a component inside any method. The this
reference is standard in JavaScript and used widely in other JavaScript libraries like jQuery, so there's nothing much to explain about it. However, React components also make use of two references that are basic to handle component data: props
and state
.
In very simple terms, data in props
can only be set and not changed (i.e. it's immutable), while data in state
is meant to keep track of changing values in a component. The following listing shows the <BannerContainer>
component with various this
, props
and state
references.
React component use of this
, props
and state
|
The following sequence of events takes place in the previous listing:
- The
ReactDOM.render()
method is called to render the<BannerContainer>
component with themessage="React 101!"
attribute. - The component's
message="React 101!"
attribute becomes accessible throughthis.props.message
inside the component. - The component's
getInitialState()
life-cycle method is called and sets two values{showBanner: true, message: this.props.message}
with the intent to change them. Note this newmessage
reference gets its initial value fromthis.props.message
and is redefined in this manner becausethis.props.message
is immutable. - The references set in
getInitialState()
become accessible throughthis.state.<reference_name>
(e.g.this.state.showBanner
,this.state.message
). - The
handleClick()
method uses thesetState()
method to updatestate
reference values. - Finally, the
render()
method contains the component's HTML output with various statements that make use ofthis.state
values and hooks to the component's methods that alterthis.state
values.
As you can now understand based on this sequence of events, a React component relies on the this.props
and this.state
references to set values for the component's rendered HTML. In the case of this.props
these values won't change in the HTML due to their immutable nature, however, those in this.state
are updated dynamically -- depending on trigger events -- and the HTML is updated accordingly.
React components with ES6 classes
The previous React component uses the initial incarnation of React components. But as with all things technology, React now offers an alternative way to construct React components based on ES6 classes. With ES6 being a newer JavaScript standard, React components using ES6 classes are becoming all the more common. Albeit, since ES6 still isn't mainstream, both React component techniques continue to be perfectly valid and supported.
An ES6-based React component can be created using React's React.Component
class. To create a React component in this manner you must use the ES6 class
and extends
keywords to create a class that inherits its behavior from React.Component
. Method declarations in React ES6 classes -- including life-cycle, custom methods and the actual HTML the component generates -- are different than those used in the first type of React components, mainly because ES6 enforces its own way of doing things. The following listing illustrates the structure of the <BannerContainer>
component used in the example that uses React ES6 class syntax.
React component structure with React.Component
class BannerContainer extends React.Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); this.handleAjaxButtonClick = this.handleAjaxButtonClick.bind(this); } handleClick(event) { } handleAjaxButtonClick(event) { } render() { return ( <div> <h4>.....</h4> </div> ); } } |
The render()
method continues to be the most important method for this other way of creating React components, since it defines the HTML for the component. So whenever you render the <BannerContainer>
component from this snippet, React outputs the HTML <div><h4>.....</h4></div>
. The only difference in the render()
method between component types is the syntax, the ES6 component version is cleaner since it isn't wrapped around function()
syntax. But things do change a little more with other component methods.
Notice there's no getInitialState()
method and the React component now has a constructor()
method that wasn't there before. ES6 classes use a special method called constructor()
-- like other OOP languages -- to initialize object instances. Because the React component is now ES6 compliant, it relies on the constructor()
method to initialize the React component and forgoes using the custom initializer getInitialState()
method.
Custom methods on ES6 class-based React components also require additional attention. In the prior React component version, custom methods (e.g. handleClick
, handleAjaxButtonClick
) were automatically bound to the instance. Following the semantics of regular ES6 classes, custom methods used in React ES6 class-based components must be explicitly binded [1]. This binding process for custom methods is done in the constructor()
method as you can see in the last listing (e.g. this.handleClick = this.handleClick.bind(this);
, this.handleAjaxButtonClick = this.handleAjaxButtonClick.bind(this);
).
In ES6 class-based React components, the use of the this
keyword, as well as React's props
and state
references function practically the same, as you can see in the following listing
React ES6 class-based component use of this
, props
and state
|
As you can see in this last listing, with the exception of a few minor syntax difference, the use of this
, props
and state
, as well the component workflow, is the same as the one described in the previous component version that uses React's pre-ES6 ad-hoc class syntax.
React component relationships and UI purity
Another important aspect of React components is they can be nested -- irrespective of the approach you decide to take, ES6 classes or classical classes -- effectively establishing relationships. If you look at the render()
method in either <BannerContainer>
component in the last listings you can see the <Banner show={this.state.showBanner} message={this.state.message}/>
statement. This reference tells React to render another React component named <Banner>
in this position of the HTML hierarchy. Notice this other <Banner>
component -- the child -- is defined with two properties or state values taken from the <BannerContainer>
component -- the parent.
This ability to create parent-child relationships between React components creates very powerful options. For example, changes in one component can be propagated to other components so that when an event happens (e.g. click, data update) the other components react to this change and take the appropriate actions.
Another important factor of React components is you can expect a lot of UI functionality, but not much of anything else. If you look at the handleAjaxButtonClick()
method in the previous examples, you can see this method contains logic that makes an AJAX call. If this last AJAX call is successful, it takes the result and updates the component's message
state variable. The interesting bit about this last method is that it uses the fetch
JavaScript library to make the AJAX call -- a library you can also see declared in a <script>
tag at the top of the index.html
page.
The use of this additional library for the simple task of an AJAX call shows just how specific the functionality offered by React is. After various React versions, it remains to be seen for React to expand beyond its core feature set to build UI components. This is a positive sign that shows how React is committed to UI functionality, compared to other JavaScript libraries that expand on non-essential features in an attempt to gain greater traction and support, a phenomenon which is all too common in JavaScript circles where dozens of libraries overlap trying to solve the same problem.
Now that you've explored React's component concepts and syntax, as well as seen working examples of React components, it's time to move on to a React deployment process that's more inline with a real life project.
Part II: React deployment with npm and webpack
As you're now aware, React components -- specifically JSX -- cannot be delivered 'as is' to a browser, they must be converted to plain JavaScript. In the React examples you just saw, a special transpiler library called Babel was added to the web page so it could be downloaded by a browser to perform the JSX conversion into plain JavaScript. This is less than ideal, because not only does this place additional load on an end user's browser, it also forces him to download an additional dependency.
Also, if you consider these past React projects are accompanied by multiple dependencies -- two React js files & the fetch library for AJAX -- it begets the question "Wouldn't it be better to bundle JavaScript dependencies so an end user downloads a single js file ?" It definitely is the recommended approach. And because React is often accompanied by many more dependencies on medium to large projects (e.g. a SPA with dozens or hundreds of JS libraries), bundling JavaScript dependencies has become a standard practice for both React projects and modern JavaScript deployments.
Npm package manager
The first thing you need for this type of JavaScript deployment is a package manager. We will use npm which is included with Node.js -- the JavaScript server side platform. Node.js is a widely used platform, so there are installers for all the major operating systems (Windows, Apple & Linux), as well as the source code if you use an esoteric operating system. Once you download Node.js [2] and install it, the npm
executable is included with the installation.
Go ahead and type npm
on a command-line prompt/shell and you will see the default output message that starts with Usage: npm <command>
. If npm
is not found or you get an error, it means you didn't install Node.js correctly. Npm has excellent documentation [3] and there are many forums (e.g. stackoverflow.com) to ask installation troubleshooting questions, so I'll leave the npm installation topic at this.
With access to npm
create a folder for the project (e.g.reactintro
) and type the following npm
command.
Create npm project without prompt
|
This last command creates a package.json
file with the configuration of a newly minted JavaScript project. If you open the file, it should look like this other listing.
npm
project configuration package.json
file
|
Don't worry about the meaning of each package.json
line for the moment, let's install some dependencies. If you recall from the examples in part I, they used the fetch
library, as well as the react
and react-dom
libraries. Let's get those to begin with by running the following sequence.
npm
dependency installation
|
The npm dependency installation syntax is npm install --save <package>@<version>
. In this case, notice the packages and their versions are exactly the same as those used in the examples from part I.
It's worth mentioning you can omit the version syntax (e.g. npm install --save fetch
) in which case npm installs the most recent package version. The --save
flag is used to tell npm to update the package.json
file with the installed package, which is helpful if you take or share your project elsewhere.
When you run the three npm install
tasks from this last list you will see the result of the outcome on the screen. If it's successful the following happens:
- A
node_modules
folder is created alongside thepackage.json
file.- This folder contains a project's packages and their dependencies. If you peek inside you should see about a dozen sub-folders with package files. This folder is really not intended for humans -- it's like peeking inside avendor
folder in PHP composer or a.m2
folder in Maven for Java -- it's intended for thenpm
tool, not you. - The
package.json
file is updated with package dependencies.- Because thenpm install
command uses the--save
flag, if you open thepackage.json
file you'll see adependencies
section. This helps with the deployment of the same JavaScript project on different machines, without having to take thenode_modules
folder.
We're almost done with dependencies. In addition to the last packages, remember the examples in part I also relied on the Babel package to transpile the React JSX component into JavaScript directly on a user's browser. Since we're now going to build the project before it hits any browser, let's install the Babel package dependency, as well as the Webpack bundler package and some other packages to achieve the build process.
npm
development dependency installation
|
I'll get to the purpose of each JavaScript package in the upcoming sections. The most important thing about this last dependency installation process is the --save-dev
flag, which is used to save the package as a project development dependency [4]. Similar to the npm --save
flag, the --save-dev
flag saves packages to the packages.json
file in a dedicated devDependencies
section.
Next, let's perform a quick test so you understand the basic purpose of npm. Copy the package.json
file in this project to a completely new folder. Placed in this new folder invoke the npm install
command, this triggers the installation of all project dependencies once again and npm creates a new node_modules
folder with all project packages. So by using an npm package.json
file, you can easily share or restart a project without having to move around the full packages.
Now that you have a basic understanding of the npm package manager and where it places files, let's move on to the next step which involves using a bundler, in this case we will use the Webpack bundler [5].
Webpack bundler
If you look over the dependencies installed with npm, you'll see there's both a webpack
and webpack-dev-server
package, the first one contains webpack's core, while the second is a webpack utility to quickly test applications. Npm already installed the executables for both these packages, so there's no further action needed. Let's test the webpack executable located inside the webpack/bin
folder in node_modules
.
Webpack executable default output
|
In this case we use the relative path to access the webpack
executable, but you can easily add this route as an executable path to your OS to access it automatically. Notice the output message says it can't find a webpack configuration file. Create a file called webpack.config.js
-- note the .js
extension for JavaScript -- and place it alongside the npm package.json
file and node_modules
folder. The next listing illustrates the contents of webpack.config.js
required to replicate the examples from part I using webpack.
Webpack configuration for React/babel transpilation, CSS and HTML bundling.
|
Let's break down the explanation of this webpack configuration into five parts:
var ... = require('....')
.- At the top there are four statements that use therequire
keyword to gain access to other modules/packages. Therequire
keyword functions just like it does in other programming languages, guaranteeing access and a unique namespace for other modules/packages.require
though isn't a standard JavaScript keyword, it's a CommonJS construct designed to make JavaScript work with modules, as I discussed earlier in Modules, namespaces & module types. Both npm/Node.js & webpack know how to work with CommonJS, but browsers don't, which is why you won't see browser-bound JavaScript withrequire
statements.entry
.- As its name implies, this section tells webpack where to look for an application's entry points. In this case, it defines one entry point calledmain
which points to./src/main.js
-- a file I'll describe shortly.output
.- Defines where to place the final bundled result. In this case, the output is sent to a file calledmain.js
under thebuild
directory relative to the main directory -- the last of which is determined using thepath
module.loaders
.- Defines the types of files to bundle and specifies processing instructions. In this case, we declare two types of files to bundle, JSX and CSS files.- JSX files.- The
test: /.jsx?$/
statement is a regular expression that tells webpack to look for files with a.jsx
extension. Theloader
statement tells webpack to usebabel-loader
to process this kind of file, which as you might recall is the same Babel library used in the examples from part I. Theexclude
statement is used to restrict the bundling of files on a given path, in this case it means that if a dependency innode_modules
contains a.jsx
file, it won't be included as part of the final bundle. Finally, thequery
statement is used to provide instructions to the loader, where thepresets: ['react']
value tellsbabel-loader
to expect to process JSX/React components [6] - CSS files.- The
test: /\.css$/
statement is a regular expression that tells webpack to look for files with a.css
extension. Theloader
statement tells webpack to useExtractTextPlugin
to process CSS files, which in itself defines its ownloader
andfallbackLoader
. It's worth mentioning webpack CSS processing/bundling accounts for three of the dependencies you installed with npm that weren't required in the example from section I.
- JSX files.- The
- Plugins.- Defines webpack plugin initialization. The
new ExtractTextPlugin("styles.css")
statement initializes the CSS processing plugin and the argumentstyles.css
defines the name of the final CSS bundle file. TheHtmlWebpackPlugin
plugin is used to generate an HTML file containing references to all the webpack generated bundles, in this case the plugin is initialized withtemplate
to use thesrc/index.html
file to generate the HTML file. The remaining three plugins -- prefixed withwebpack
-- are for optimization purposes and intended to reduce the size of the final JavaScript bundle by using compression and pruning unnecessary module artifacts (e.g. log statements). These three optimization plugins alone can reduce a final webpack bundle size by as much as 500% (e.g. a 710Kb bundle can be reduced to a 141Kb bundle with these optimizations).
Now that you have a webpack configuration file ready to transpile and bundle your project files, as well as npm equipped with all project dependencies, let's take a look at the project's folder structure.
React project layout for npm/webpack
The following listing illustrates a React project folder and file structure for use with npm/webpack, elements in bold represent new folders/files I'll describe shortly.
React Project folder & file layout for npm/webpack
|
As you can see, there are a total of four new files. Just like in part I, a React project built with npm/webpack can be either based on pre-ES6 constructs or ES6, so I'll also create two sub-sections to describe both approaches. But before I do that, I'll describe the contents of the style.css
and index.html
files which don't change irrespective of using ES6 or pre-ES6 syntax.
The style.css
file contains a simple CSS class used by a React component.
CSS style.css
file
|
The index.html
file is used as a template to generate an HTML web page that references all the webpack bundled resources.
React index.html
file
|
As you can see, this HTML file contains the same <div id="banner-container"></div>
element used in the examples from part I, which loads the React component on the web page. But notice in this case there's no trace of JavaScript or CSS resources! so what's happening ? This last file isn't the web page that's sent out to end users, but rather a template that's used to generate the final web page. When you trigger the webpack build process, webpack uses this file and adds references that point to whatever bundles (JS & CSS) it creates. This template functionality is provided by webpack's Html Webpack plugin which you installed with npm and declared in the webpack.config.js
file.
React & webpack pre-ES6 syntax
Now let's explore the files associated with a project that uses pre-ES6 syntax.
First let's take a look at the webpack entry file named main.js
, the following snippet shows its contents
Webpack entry main.js
file
|
It doesn't get much simpler than this file which uses require
statements -- CommonJS syntax -- to tell webpack to load the contents from the ./assets/css/style.css
and ./app/banner.jsx
modules/files.
Now let's explore the banner.jsx
file that contains the React components and whose contents are almost identical to the pre-ES6 exercise from part I.
React banner.jsx
file
|
You already created React components using the pre-ES6 ad-hoc API in part I, so the banners.jsx
file contains exactly the same components, which correspond to the contents between <script type="text/babel"> and </script> in the pre-ES6 example. However, there's a notable difference in how both examples gain access to the React libraries. In this case the file uses the require
statement to gain access to both the react
and react-dom
modules, where as in the example from part I the web page uses a <script>
tag to load these same libraries that generate the React components.
There's not much more to add about this file since its React components were already described in part I. Webpack along with Babel are charged with transpiling and bundling the contents of this file when you execute the build process.
Now let's take a look at the ES6 version of this same React/Webpack project.
React & webpack ES6 syntax and requirements
The first thing you need to do to use ES6 in a React/Webpack project is install the corresponding dependency in npm to be able to transpile ES6. Run the following command npm install --save-dev babel-preset-es2015
-- note ES2015 is the same as ES6, the 2015 refers to the ECMAScript release year and the 6 refers to the ECMAScript version. This adds the ES2015(ES6) module to node_modules
and updates npm's package.json
to reflect this new package in the devDependencies
section.
Next, you need to update the webpack webpack.config.js
configuration file so it also expects to process ES6. The following snippet highlights the update you need to make to the webpack.config.js
configuration file presented earlier.
Webpack configuration for React/babel transpilation updated with ES6 support
|
Notice the additional es2015
value for the presets
list in the loaders
query
section.
Now let's update the remaining React project files to use ES6. The following listing illustrates the main.js
updated to ES6.
Webpack entry main.js
file using ES6
|
Notice the file now uses the ES6 import
keyword, instead of the require
keyword which is part of CommonJS. As noted earlier in Modules, namespaces & module types, ES6 modules are the emerging standard but are still not mainstream.
Next, let's look at the actual React components using ES6 classes.
React banner.jsx
file using ES6
|
Since you already created React components using ES6 classes in part I, the banners.jsx
file contains exactly the same components, which correspond to the contents between <script type="text/babel"> and </script> in the ES6 example. However, there's a notable difference in how both examples gain access to the React libraries. In this case the file uses the import
keyword -- part of ES6 -- to gain access to both the react
and react-dom
modules, where as the example from part I uses a <script>
tag to load these same libraries that generate the React components.
Now that you've seen all the necessary details about this new React/Webpack project, it's time to build it and run it.
Build and run React webpack projects
All the heavy lifting has been done in the configuration files and the main project files. Now run the webpack
executable alongside the webpack.config.js
configuration. After you run the webpack
executable, you'll see the results of the build process.
Webpack executable to build project
|
Per the webpack configuration, the results of the build process are placed in the build
folder. If you go to the build
folder you'll see three files: main.js
which bundles all the necessary JavaScript to run the project, styles.css
which bundles all the CSS that belongs to the project and an index.html
file -- based on the index.html
template -- with references to the main.js
and styles.css
files.
Finally, run the webpack-dev-server.js
executable to start a web server to test application using the following snippet
Webpack dev server to test application
|
Notice the webpack dev server uses the --content-base
flag to load its root directory on the build
folder. Next, open a browser and point it to localhost:8080
to see identical React applications as the ones you did in part I, the difference is these last examples bundle every JavaScript dependency and the React component transpilation process is performed beforehand.