Bundling code using Webpack

Amir Mustafa
Jul 4 · 6 min read

Prerequisites:

Basic understanding of TypeScript.

What is Webpack?

→ Webpack is the code bundling tool that helps us in optimizing the code performance.

→ In a real-time big project, there will be many ts files (maybe more than 100 files). TypeScript uses tsc — watch command to transpile these files to js file

→ So there will be the same number of JS files will be generated (say 100 js files).

Multiple files generated inside dist folder

→ If we observe the above screenshot:

src: This directory contains all the tsc files of the application

dist: The same number of js files will be generated which will be rendered in the browser.

→ In the above Network tab of the chrome browser development tool we find all the JS files rendered here.

ISSUES WITH THE ABOVE APPROACH:

a. Multiple files will call multiple HTTP requests. Every call will take some time to get a response. Overall file response will take lots of time which will cost site performance.

b. We can observe this waterfall tab in the above screenshot.

White box line: In the HTTP request tells us the latency time and

Blue box line: is the response we get.

c. Here we are developing in local server. Imagine if we deploy in the production server, the page loading time will increase more.

SOLUTION: Webpack

This will generate one bundle.js file inside the dist folder.

The number of HTTP calls will be one. Hence the overall app performance will be an increase

Video 1: Webpack installation and some overview:

Final output:

Inside
Bundle.js is the only JS file that will be rendered in the browser

Let us start the development of Webpack.

STEP1: In the project, the terminal installs the below plugins:

npm install — save-dev webpack webpack-cli webpack-dev-server typescript ts-loader;

STEP2: Go to tsconfig.ts file

"target": "es6",   "module": "es2015","sourceMap" true,// "rootDir": "./src",    // this must be commented

rootDir: TypeScript converts ts file into equivalent JS file and keeps it using this key. Commenting on it will stop the default creation of JS files.

target: This can be es5 or es6 based on the browser choice.

sourceMap: This will help to debug TS files in the browser.

module: This must be “es2015”

STEP3: Create webpack.config.js. Webpack by default searches for this file.

This page follows Node js syntax.

module.exports = {  mode: 'development',  entry: "./src/app.ts",  output: {    filename: "bundle.js",    path: path.resolve(__dirname, 'dist'),    publicPath: '/dist',  },` devtool: 'inline-source-map',  module: {    rules: [      {        test: /\.ts$/,        use: 'ts-loader',        exclude: /node_modules/      }    ] }, resolve: {   extensions: ['.ts', '.js'] } };

Explaining each key above:

  1. mode: This can be development or production. In production minified bundle code will be generated
  2. entry: This is the starting page of the application, here app.ts

3. output.filename: This is the bundled file name that will be generated (i.e. bundle.js)

4. output.path: Path where the bundled file will be generated.

5. output.publicPath:

a. We will first use the Lite server to create dist/bundle.js — for that path key is enough.

b. When we use Webpack server, physically dist directory will be empty and will come from webpack server memory. This path to add only when webpack server is used (which is generally same as path key)

6. devtool: In development — inline-source-map, for production— can be none or eval

Refer — https://webpack.js.org/configuration/devtool/

7. modules.rules.test: This contains a list of rules. For this app, we tell webpack which monitor all the ts file

8. modules.rules.use: using TS loader

9. modules.rules.exclude: Webpack will ignore monitoring specified directory here.

10. resolve.extensions: In all the import statements, no need to write extensions i.e .js and .ts, webpack will monitor it.

STEP4: Go to package.json file

{   “name”: “understanding-typescript”,   “version”: “1.0.0”,   “description”: “Understanding TypeScript Course Setup”,   “main”: “app.js”,   “scripts”: {   “test”: “echo \”Error: no test specified\” && exit 1",   “start”: “lite-server”,   “build”: “webpack”       // Write this build line},“keywords”: [  “typescript”,  “course”],“author”: “Amir Mustafa”,“license”: “ISC”,“devDependencies”: {  “lite-server”: “².5.4”,  “ts-loader”: “⁹.2.3”,  “typescript”: “⁴.3.5”,  “webpack”: “⁵.41.1”,  “webpack-cli”: “⁴.7.2”,  “webpack-dev-server”: “³.11.2” }}

STEP 5: Now run the below commands in terminal (open in three terminals in the project directory)

npm run build // creates bundle.js inside dist directorynpm start     // starts lite servertsc –watch    // Typescript watching

→ Now we see only one bundle.js downloaded in the browser, hence less waterfall latency

→ Hence no unnecessary HTTP requests for multiple pages

→ In your index.html file

<script type="module" src="dist/bundle.js"></script>

Video 2: Convert from multiple files to one bundle.js:

C. Using Webpack Server:

Why use Webpack Server?

i. When we write our code, auto-refresh in the browser happens just like React with this server.

ii. With Lite server, we use to hit npm run bundle again and again. after a code change. No need for the same here.

iii. At present bundle.js file is created in the dist folder. With webpack server, no physical bundle.js file will be created. This will be rendered from the memory of the webpack server. Hence code is more optimized.

We need to write inside webpack config which we discussed above.

publicPath: '/dist',

STEP1: in package.json

"start": "npx webpack serve",

You can also follow this change here:

https://github.com/AmirMustafa/DragNDrop/commit/f44862849d4cd31d1089d34efb61dd13c1ef079a

STEP2: In webpack.config.js

const path = require('path');module.exports = {
mode: 'development',
entry: "./src/app.ts",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist', // webpack memory serve - bundle.js
},
devtool: 'inline-source-map',
module: {
rules: [

https://user-images.githubusercontent.com/15896579/124289049–7e322380-db6f-11eb-95e6–17b5d2582f4b.png

→ Now hen you run npm start this time instead of lite server, webpack server will run and open in :8080 port

→ Observation: This time dist directory will be empty and file will be served from webpack memory

Video3: Converting from Lite server to Webpack server:

D. Preparing bundle.js for Production environment

In the production environment, bundle code should be optimized, non-readable.

STEP1: npm install clean-webpack-plugin

STEP2: in package.json we will refer to the new production config file.

"build": "webpack --config webpack.config.prod"

STEP3: Create a new file wepack.config.prod.js

const path = require('path');
const CleanPlugin = require('clean-webpack-plugin');
module.exports = {
mode: 'production',
entry: "./src/app.ts",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, 'dist'),
},
devtool: "eval",
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.ts', '.js']
},
plugins: [
new CleanPlugin.CleanWebpackPlugin() // clear everything, before writing in dist folder
],
};

→ Clean Plugin will delete everything inside the dist folder, before creating a new bundle.js file

→ Also removed publicPath: ‘/dist’ from the output

Closing thoughts:

Webpack is used in most big applications to enhance code optimization and faster web application loading.

I hope you have learned something new today. This will help you for getting started with Webpack.

Thank you for being till the end 🙌 . If you enjoyed this article or learned something new, support me by clicking the share button below to reach more people and/or give me a follow on Twitter to see some other tips, articles, and things I learn and share there.

Geek Culture

Proud to geek out. Follow to join our +1M monthly readers.