Tutorial #4 — Live Project Discussion and Front-End Setup
There is no better way to learn than to try out things hands-on, so we ought to continue further tutorials by trying to implement a Blog Management System (An app where readers can subscribe to topics, mark their progress, review posts etc). We would then setup webpack for bundling front-end code and npm (yarn) to download packages required for developing the UI. Without wasting much, let’s hop on!!
Part 01: Blog Management System
To keep things simple, we limit ourselves to only crucial features of our blog management system:
- User Registration & Login
- Blogs Management: (mark as read, track progress, review/recommend etc.)
- Notifications (automated email etc.)
The above list of features we feel are sufficient to get a grasp of the architecture and functioning of the system. Later we can add additional functionalities such as premium content, suggestions, tagging of posts etc. We shall cover implementation of each of the above features in forthcoming posts, but for now let’s setup our client-end code.
Part 02: Setting up the Client Side
First of all, one must have nodejs installed. Download from here if you haven’t already. The global config file for nodejs resides at ~/.npmrc
. One can add any settings from the available list of options, e.g. for setting proxy:
proxy=http://<username>:<password>@<proxy-server-url>:<port>
https-proxy=https://<username>:<password>@<proxy-server-url>:<port>
Create a directory under the project root called client
. Create a new file called package.json
, put the contents of the following gist there.
Open Terminal and navigate to the client directory and execute: npm i
. All the necessary packages will get installed and placed in a node_modules
sub-directory, or you can go along with the latest versions of the packages by runnin:
$ npm install <package-name> --save. (To save it to dependencies)
$ npm install <package-name> --save-dev (To save it to development-dependencies)
Next, we need to set-up webpack. It is a package bundler which collects all the javascript code written in different files under different directories, and combines them into a single file called a bundle. That bundle is served during production and development. Webpack thus also needs to be fed some configuration settings for bundling.
Create 2 new files under client
directory called webpack.common.js
and webpack.dev.js
.
webpack.common.js : The common bundling settings used during both production and development. The keys and their meanings are as follows:
entry
: Describes the entry point of the app as from being./src/index.js
, which we will create afterwords. Usebabel-polyfill
for emulating ES2015 environment (for older browsers). To dig deeper into polyfills, readers can refer this article.module
: Describes various rules (file types and how to handle them). Each rule has an appropriate loader with additional options describing how to handle the code present in the respective file type. e.g. for alljs/jsx
files, code has to go through thebabel-loader
. Similarly for other file types, we have other loaders.
webpack.dev.js : To create development code, we need additional settings along with the above common ones. We thus create a seperate webpack.dev.js
. We use webpack-merge
to merge the common and dev settings. The keys and their meaning in the dev file are as:
mode
: ‘development’ indicates webpack that the settings here are purely to be used during development.optimization
: Optimization settings such as minimizer (TerserPlugin is the default minimizer), dead-code elimination by not bundling unused exports (usedExports: true), merge duplicate chunks, etc. For more extensive options, refer here.output
: Defines the output configuration. Here we setpublicPath
to/
indicating bundle code will be loaded at <root-url>/. e.g. settingpublicPath: /home
will load client side code athttp://localhost:8080/home
.filename
andchunkFilename
is set to[name]-[hash].js
because each time webpack bundles code, it generates a new hash which it appends to each js file name. e.g.js-4ad910306c03c.js
.devServer
: Settings for webpack-dev-server. (more about devServer in next section).compress: true
serves gzip compressed code.stats: errors-only
shows only errors during watching changes.historyApiFallback: true
allows fallback to index.html in case a 404 error occurs (Read more about history API and fallback here).plugins
: We are using HtmlWebpackPlugin which is especially useful for webpack bundles that include a hash in the filename which changes every compilation, as in ours.
Next, create a new file under client
names .babelrc
and populate it’s contents with:
.babelrc
serves as the configuration file for babel-loader
(see webpack.common.js
). Presets are a set of plugins assembled together. e.g. The react-preset comprises of 2–3 plugins described here. Plugins as the name suggests perform additional specific tasks, e.g. lodash
reduces bundle size by cherry-picking lodash imports. plugin-syntax-dynamic-import
makes code-splitting by dynamic imports possible (Don’t worry if you didn’t get what we meant. It will be discussed in detail in upcoming posts).
Finally, create an src
directory under client
where all our application code shall reside. The final directory structure should look as:
Part 03: Important npm scripts & packages
We basically need 2 important scripts, namely start
and build
for development and production purposes. Check the scripts portion of package.json for the aliased command. start
gets the webpack-devServer running. Webpack-devServer is a simple client side web-server which watches for changes in client side code during development, quickly bundles and reloads to display the changes. It is a very useful utility for development as one doesn’t expect to build a production bundle each time to see the changes made during development.
start: webpack-dev-server --open --config webpack.dev.js
webpack-dev-server uses webpack.dev.js
file as it’s config file.
build: webpack --config webpack.prod.js
Similarly, build
generates the production bundle for deployment. We shall leave things here and write out production config settings later. Some of the npm packages and why we are using are worth talking about:
- Babel packages: Babel is a JS transpiler mainly used for converting ES6 syntax code to JS code that browsers are able to process (ES6 code involves arrow functions, spread operator, let-const etc). However, it also can do other amazing things based on the presets. e.g. (dynamic import ~ code splitting), reducing lodash bundle size etc.
- Webpack packages: Webpack packages serve the purpose of bundling code. devServer and merge has already been explained. Bundle-Tracker is useful to generate stats and most importantly publicPaths to js bundles required in production. It’s role can be better understood when we will cover serving production code and django-webpack-loader. Bundle-Analyzer is a package used to profile and observe bundle size statistics. An example output is shown below:
- material-ui packages: The main open-source React UI framework used to develop our application.
- axios: Promise-based API client for making network requests. (GET, POST etc.)
- connected-react-router, react-router-dom, history: Libraries required for client-side routing. History object stores the current location, match and parameters during routing from one page to another.
- react: Doesn’t need explanation I think 😄
- redux, react-redux: Global State Management library and it’s bindings with React Components. Redux is all about having a single source of data. Components subscribe to changes in the store, and interact with it by dispatching actions. Redux has a lot of things to discuss about and thus requires a seperate post (coming soon).
- redux-saga: Side-effects management library used in conjunction with Redux. (mainly used for network API calls or any other asynchronous tasks). Redux-Saga too requires a seperate post (coming soon) for a proper understanding of its underlying principles (saga pattern).
Above packages were the most crucial ones. The rest will be explained as they are used. That is all for this post.
We shall continue with Django App setup and Server-side directory structure.
For Regular Updates and other blogs of the this tutorial series. You may Follow — React DJ Facebook Page
Our series of tutorials are currently organized at — srplabs.in
For Introduction of the Tutorial Series You may read — Building Practical Web Applications with React & Django