React + Webpack + TypeScript Project Setup

React + Webpack + TypeScript Project Setup

React + Webpack + TypeScript Project Setup: Let's get React and TypeScript setup, its a lot easier than you think!

React + Webpack + TypeScript Project Setup: Let's get React and TypeScript setup, its a lot easier than you think!

TL;DR: Can’t possibly summarize this in a single sentence but there is a repo that you can fork which has all of the boilerplate setup.

Let’s Get Started!!

Firstly you will need to create a directory/repo for your project, once you have done this you will need to initialize the project. Run one of the following snippets in your terminal to do so:

//If you want to use npm 
npm init
//If you want to use yarn 🧶
yarn init

Just follow along with the prompts in the terminal, once the initialization is complete you should see a package.json file in the directory. If you don’t know what a package.json file is then this post is not for you, I would recommend that you play with React and npm more before continuing.

Add Some Dependencies 😵

The 3 dependencies that you’ll need are react, react-dom, and typescript which are all pretty straightforward, but you’ll also need 24 devDependencies.

To install the 3 dependencies run the following

//Optionally you can install styled-components
//npm
npm install react react-dom typescript
//yarn 🧶
yarn add react react-dom typescript

For this post, we’ll be using babel so you’ll need to install babel-loader, a couple of babel plugins, and some babel presets.

Something to note is that as of babel v7, babel ships with Typescript support so we don’t need a separate TypeScript loader 😃.

//npm
npm install babel-loader @babel/plugin-external-helpers @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread @babel/preset-env @babel/preset-react @babel/preset-typescript --save-dev
//yarn 🧶
yarn add babel-loader @babel/plugin-external-helpers @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread @babel/preset-env @babel/preset-react @babel/preset-typescript -D

Ok on to installing the testing specific devDependencies. We’ll be using Jest and Enzyme along with some enzyme specific dependencies.

//npm
npm install enzyme enzyme-adapter-react-16 enzyme-to-json jest ts-jest --save-dev
//yarn 🧶
yarn add enzyme enzyme-adapter-react-16 enzyme-to-json jest ts-jest -D

Ok just a couple more dependencies, obviously we need Webpack, Wepback plugins, and the types for the various dependencies

//npm
npm install @types/enzyme @types/enzyme-adapter-react-16 @types/jest @types/react @types/react-dom html-webpack-plugin source-map-loader webpack webpack-cli webpack-dev-server webpack-hot-middleware --save-dev
//yarn 🧶
yarn add @types/enzyme @types/enzyme-adapter-react-16 @types/jest @types/react @types/react-dom html-webpack-plugin source-map-loader webpack webpack-cli webpack-dev-server webpack-hot-middleware -D

Oof ok we’re done with the dependencies finally… 🎊

Webpack Config 🛠

You should be somewhat familiar with Webpack configs but all we’re doing is checking the mode and adjusting the config based on the environment mode (production or development). Since I’m using styled-components the only loader I need is babel-loader with the various plugins and presets, but if you have CSS in your project you’ll need a CSS loader.

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = (env, { mode = 'development' }) => {
  const config = {
    mode,
    entry: {
      app: './src/index.tsx',
    },
    devtool: '',
    resolve: {
      extensions: ['.js', '.jsx', '.ts', '.tsx'],
    },
    module: {
      rules: [
        {
          test: /\.(js|jsx|tsx|ts)$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: [
                '@babel/preset-env',
                '@babel/preset-react',
                '@babel/preset-typescript',
              ],
              plugins: [
                '@babel/plugin-external-helpers',
                'babel-plugin-styled-components',
                '@babel/plugin-proposal-class-properties',
                '@babel/plugin-proposal-object-rest-spread',
              ],
            },
          },
        },
      ],
    },
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'index.js',
      libraryTarget: 'umd',
      publicPath: '/dist/',
      umdNamedDefine: true,
    },
    optimization: {
      mangleWasmImports: true,
      mergeDuplicateChunks: true,
      minimize: true,
      nodeEnv: 'production',
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"production"',
      }),
    ],
  };

  /**
   * If in development mode adjust the config accordingly
   */
  if (mode === 'development') {
    config.devtool = 'source-map';
    config.output = {
      filename: '[name]/index.js',
    };
    config.module.rules.push({
      loader: 'source-map-loader',
      test: /\.js$/,
      exclude: /node_modules/,
      enforce: 'pre',
    });
    config.plugins = [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"development"',
      }),
      new HtmlWebpackPlugin({
        filename: path.resolve(__dirname, 'dist/index.html'),
        template: path.resolve(__dirname, 'src', 'index.html'),
      }),
      new webpack.HotModuleReplacementPlugin(),
    ];
    config.devServer = {
      contentBase: path.resolve(__dirname, 'dist'),
      publicPath: '/',
      stats: {
        colors: true,
        hash: false,
        version: false,
        timings: true,
        assets: true,
        chunks: false,
        modules: false,
        reasons: false,
        children: false,
        source: false,
        errors: true,
        errorDetails: true,
        warnings: false,
        publicPath: false,
      },
    };
    config.optimization = {
      mangleWasmImports: true,
      mergeDuplicateChunks: true,
      minimize: false,
      nodeEnv: 'development',
    };
  }
  return config;
};

TypeScript Config 👨‍💻

Everything in the TypeScript configuration is opinionated, what I mean by that is that you can edit it to your heart’s content and it shouldn’t break your application, what I have in the repo is just what I like as some defaults. Just make sure that the tsconfig.json file is at the root of your project.

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "jsx": "react",
    "module": "amd",
    "noImplicitAny": true,
    "outDir": "./dist/",
    "preserveConstEnums": true,
    "removeComments": true,
    "sourceMap": true,
    "target": "es6",
    "moduleResolution": "node",
    "strict": true,
    "alwaysStrict": true,
    "strictNullChecks": false,
    "downlevelIteration": true
  },
  "include": [
    "./src/"
  ],
  "exclude": [
    "node_modules"
  ]
}

Jest Config 🧪

The Jest configuration file is used to configure Jest, the testing framework that we’ll be using. Make sure to place the jest.config.json file at the root of your project. Again like the TypeScript config, this is opinionated so please feel free to change it, everything is pretty standard though: (We’ll talk about the setupEnzyme.js file a second)

{
  "roots": [
    "<rootDir>/src"
  ],
  "transform": {
    "^.+\\.tsx?$": "ts-jest"
  },
  "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(ts|tsx)$",
  "testPathIgnorePatterns": [
    "./src/__tests__/setupEnzyme.ts"
  ],
  "collectCoverageFrom": [
    "src/**/*.{js,jsx,ts,tsx}",
    "!/node_modules/"
  ],
  "moduleFileExtensions": [
    "ts",
    "tsx",
    "js",
    "jsx"
  ],
  "snapshotSerializers": [
    "enzyme-to-json/serializer"
  ],
  "setupFilesAfterEnv": [
    "<rootDir>/src/__tests__/setupEnzyme.ts"
  ],
  "moduleNameMapper": { 
    "\\.(css|less|scss|sass)$": "identity-obj-proxy" 
  }
}

Src 🚗

(These emojis mean nothing 😆)

At the root of your project, you’ll want to create a src directory where all of the project code will live. Inside of the src directory, we’ll have 3 directories, __tests__ this is where all of our tests will live (Some people are hella opinionated about where this lives, so it is really up to you), components obviously where your components live, and declerations this is where we will be putting the declaration files for our project. Of course, you can name these directories whatever you want and you can create other directories if you would like as well, this is just a suggested project architecture, just note that you may have to edit the various configurations if you don’t follow this architecture exactly.

Alongside these directories, we have 2 files, index.tsx, which is the entry point for the project, and index.html, which is the template html file used by the HtmlWebpack plugin.

Inside of the __tests__ directory, you’ll need to create a file named setupEnzyme.ts , this file is referenced in the jest.config.json and has a really simple config for Enzyme.

import * as Enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({
  adapter: new Adapter()
});

Go ahead and create a simple component and use it in the project entry point ( index.tsx ) and run the following command in the terminal:

npx webpack-dev-server -open -colors -hot -mode development

A browser window should pop open and you should see your component (make sure you check your terminal for errors though)!

Yay, you’re done!!! 🍰

You have all you need to get your React TypeScript project up and running. If you want to access all of the source code you can go to the following github repo. If you want to suggest a change make a pull-request!

Mobile App Development Company India | Ecommerce Web Development Company India

Mobile App Development Company India | Ecommerce Web Development Company India

Best Mobile App Development Company India, WebClues Global is one of the leading web and mobile app development company. Our team offers complete IT solutions including Cross-Platform App Development, CMS & E-Commerce, and UI/UX Design.

We are custom eCommerce Development Company working with all types of industry verticals and providing them end-to-end solutions for their eCommerce store development.

Know more about Top E-Commerce Web Development Company

URLs and Webpack in Reactjs

URLs and Webpack in Reactjs

URLs and Webpack in Reactjs - I am still a newbie in ReactJS. I've been following series of tutorials and articles on the framework and decided to start putting what I've learnt so far into practice.

My website, dillionmegida.com was built with PHP. You could check it out as I highly appreciate reviews. I'm though aspiring to be a full-stack javascript developer so I'm in some way trying to depart from PHP :)

I decided to replicate my homepage using React and to broaden my skills in using components.

It was going quite successful until I tried using an <img> JSX element. I used it like;

import React from 'react'
 
let dpStyle = {
    // Some styles
}
 
let Profilepic = () => (
    <div className={dpStyle}>
        <img src='../img/deee.jpeg' alt='My profile picture'/>
    </div>
)
export default Profilepic;

The img folder was a sub-directory of the src folder.

My aim here was to have my profile picture as a component with some styling to be used on my homepage and any other desired page. The src for the img tag was not been used appropriately as my image was not displayed.

I paused to think of the problem, inspected my page and discovered the src displayed there was exactly as I inputted it. So silly of me :( I made some researches which helped me remember that most attributes of JSX element are not as mostly used with HTML, but have to be enclosed in curly braces.

import React from 'react'
 
let dpStyle = {
    // Some styles
}
 
let Profilepic = () => (
    <div className={dpStyle}>
        <img src={'../img/deee.jpeg'} alt='My profile picture'/>
    </div>
)
export default Profilepic;

I tried rendering the page again and my image was still not displayed.

Funny enough, I quickly thought of a trick (for the first time);

...
import Dp from '../img/deee.jpeg'
...
let Profilepic = () => (
    <div className={dpStyle}>
        <img src={Dp} alt='My profile picture'/>
    </div>
)

To my amazement, it worked. I was excited and at the same time sad, with feeling of little guilt. I didn't know why. lol. I said to myself, 'I am not doing the right thing :(' and also asked myself, 'Is react as crazy as this?'

I headed back to google to make some more research and got to discover that the webpack that React (create-react-app) automatically installed had been configured to use the public folder (at the same level with src folder) for relative URLs (such as my image URL).

Using ...<img src={'../img/deee.jpeg'} />..., React was actually checking the public folder for the image sub-directory which it couldn't find.

Solution

1. Change the location of the image folder

I changed the location of the image folder making it a sub-directory under the public directory and it worked as expected.

2. Use the require keyword

Just as the import keyword is used for relative URLs, the require keyword does same. So, I was able to do this;

import React from 'react'
 
let dpStyle = {
    // Some styles
}
 
let Profilepic = () => (
    <div className={dpStyle}>
        <img src={require('../img/deee.jpeg')} alt='My profile picture'/>
    </div>
)
export default Profilepic;

and in the other pages where the Profilepic component was required and used, my image displayed perfectly. :D

Like I said, I am still a newbie at ReactJS but I hope this little experience would be helpful for you too. There are other super powers of webpacks too which I would still be learning. Please do share in the comment section corrections on this article and also helpful Tips.

I'll be documenting my experience in my ReactJS journey as much as I can. Stay tuned and thanks for reading.

Originally published by Megida Dillion at dillion.hashnode.dev

=======================================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Learn More

☞ Understanding TypeScript

☞ Typescript Masterclass & FREE E-Book

☞ React - The Complete Guide (incl Hooks, React Router, Redux)

☞ Modern React with Redux [2019 Update]

☞ The Complete React Developer Course (w/ Hooks and Redux)

☞ React JS Web Development - The Essentials Bootcamp

☞ React JS, Angular & Vue JS - Quickstart & Comparison

☞ The Complete React Js & Redux Course - Build Modern Web Apps

☞ React JS and Redux Bootcamp - Master React Web Development


React Web Development: A Guide to Develop Progressive Web Applications

React Web Development: A Guide to Develop Progressive Web Applications

Outperform your competition with progressive web development and React.

Progressive web applications (PWAs) quickly gained popularity because they are web performance applications based on fast performance, streamlined to provide a mobile app-like experience. PWAs are built using HTML, CSS, and JavaScript to create a level of availability and performance equivalent to that of native mobile applications. They respond quickly, consume less data, store more space, and support push notifications and offline use in the browser.

Building a progressive web application has now become the web development trend that every business wants to follow. Significant players like Twitter and Flipboard have recently rolled out their progressive web apps to provide a mobile experience for users, without requiring them to install the app. In this article, you will learn how to build a progressive web application using React. Let's get started.

Step One — Set up the React Application

First, create a React application with create-react-app. To do so, you need to run the following commands:

  • npm install -g create-react-app
  • create-react-app pwa-app

Now, install React Router:

You need to replace the content of src / App.js using the code below to get a basic template with navigation.

import React, { Component } from 'react';
import { Router, browserHistory, Route, Link } from 'react-router';
import './App.css';

const NavBar = () => (
<div className="navbar">
<Link to="/">Feed</Link>
<Link to="/profile">Profile</Link>
</div>
);

const Template = ({ title }) => (
<div>
<NavBar />
<p className="page-info">
This is the {title} page.
</p>
</div>
);

const Feed = (props) => (
<Template title="Feed"/>
);

const Profile = (props) => (
<Template title="Profile"/>
);

class App extends Component {
render() {
return (
<Router history={browserHistory}>
<Route path="/" component={Feed}/>
<Route path="/profile" component={Profile}/>
</Router>
);
}
}
export default App;

Now, you'll have to update the default styles by replacing your src/App.css with the styles below to make your application look clean.

.navbar {
background-color: #01C8E5;
text-align: center;
}

.navbar a {
display: inline-block;
padding: 10px;
color: #fff;
text-decoration: none;
}

.page-info {
text-align: center;
font-weight: bold;
}

Then, run npm start to test the application in the browser. It is basically an application with two routes. Now, you will convert it to PWA.

Step Two — Lighthouse Setting and Auditing

Lighthouse is an automated open-source tool for testing applications against PWA checklists. It facilitates audits for accessibility, performance, and more.

Check your application with Lighthouse. Click the Lighthouse icon from the top right corner in Chrome and then click the "Create Report" button. The generated report will look like this:

Creating a report to test your PWA with Lighthouse

Fix all failed audits.

Step 3 — Sign Up for a Service Staff

Service employees are proxy servers that connect the application and the network. With Service Worker, you will have to block network requests and save cached files. It allows your application to work even with an unavailable system.

Create an empty worker.js file in your application's general directory and add the following code to that file.

// Flag for enabling cache in production
var doCache = false;

var CACHE_NAME = 'pwa-app-cache';

// Delete old caches
self.addEventListener('activate', event => {
const currentCachelist = [CACHE_NAME];
event.waitUntil(
caches.keys()
.then(keyList =>
Promise.all(keyList.map(key => {
if (!currentCachelist.includes(key)) {
return caches.delete(key);
}
}))
)
);
});

// This triggers when user starts the app
self.addEventListener('install', function(event) {
if (doCache) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
fetch('asset-manifest.json')
.then(response => {
response.json();
})
.then(assets => {
// We will cache initial page and the main.js
// We could also cache assets like CSS and images
const urlsToCache = [
'/',
assets['main.js']
];
cache.addAll(urlsToCache);
})
})
);
}
});

// Here we intercept request and serve up the matching files
self.addEventListener('fetch', function(event) {
if (doCache) {
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
}
});

Now, check if the browsers support service staff and then register worker.js. To do this, you need to add the following script to the file public/index.html (note that shrink-to-fit=no in the viewport meta tag has been deleted).

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('worker.js').then(function(registration) {
console.log('Worker registration successful', registration.scope);
}, function(err) {
console.log('Worker registration failed', err);
}).catch(function(err) {
console.log(err);
});
});
} else {
console.log('Service Worker is not supported by browser.');
}
</script>
</body>
</html>

You must restart your application and reload the browser after which you will see the Successful registration of member workers on the developer console. Now, recreate the Lighthouse report.

Step 4 - Improve the Progressive Nature of the Application

Your application will display an original blank div until the JavaScript loads and React hooks the original route. You must make sure your application works without downloading JS and displaying a bit of CSS and HTML before React takes effect. Your updated Index.html will look like this:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>React App</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.navbar {
background-color: #01C8E5;
text-align: center;
}
.navbar a {
display: inline-block;
padding: 10px;
color: #fff;
text-decoration: none;
}
.page-info {
text-align: center;
font-weight: bold;
}
</style>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root">
<div class="navbar">
<a href="/">Feed</a>
</div>
<p class="page-info">
Loading an awesome app...
</p>
</div>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('worker.js').then(function(registration) {
console.log('Worker registration successful', registration.scope);
}, function(err) {
console.log('Worker registration failed', err);
}).catch(function(err) {
console.log(err);
});
});
} else {
console.log('Service Worker is not supported by browser.');
}
</script>
</body>
</html>

Now, use Lighthouse to retest your application, and you'll see an improvement in the performance of the application.

Step 5 - Add the Splash Icon

You are required to add a 512x512 icon to display on the screen. To do so, you will have to update the manifest.json file and add the t0 icon to the public directory.

{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

Also, use the following meta tags to allow the browser to determine that your application is a PWA.

<!-- Tell the browser it's a PWA -->
<meta name="mobile-web-app-capable" content="yes">
<!-- Tell iOS it's a PWA -->
<meta name="apple-mobile-web-app-capable" content="yes">
Step 6 — Implement PWA

Now, only HTTPS is missing, and the cache can be fixed after you deploy the application. Update the doCache flag with true in the worker.js file. Create a new project in the firebase dashboard and name it "Pwa Application." Then, run the following command in the project directory:

npm install -g firebase-tools
firebase login
firebase init

Your Firebase.json will look like this:

{
"hosting": {
"public": "build",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}

After initializing, building and deploying your application.

  • npm run build
  • firebase deploy

You will see results after you test the application using Lighthouse on the deployed URL.

Final product with Lighthouse

Finally, you have created your first progressive web application with React.js!

Originally published by Manoj Kumar Bardhan at  dzone.com

=======================================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Learn More

☞ Understanding TypeScript

☞ Typescript Masterclass & FREE E-Book

☞ React - The Complete Guide (incl Hooks, React Router, Redux)

☞ Modern React with Redux [2019 Update]

☞ The Complete React Developer Course (w/ Hooks and Redux)

☞ React JS Web Development - The Essentials Bootcamp

☞ React JS, Angular & Vue JS - Quickstart & Comparison

☞ The Complete React Js & Redux Course - Build Modern Web Apps

☞ React JS and Redux Bootcamp - Master React Web Development