MODULE -5
***(Refer w3 schools for remaining topics)
Schema Initialization
A schema is like a blueprint or structure that defines:
What fields your documents should have
What types those fields should be
Since MongoDB does not enforce a schema, there is really no such thing as a schema
initialization as you may do in other databases. The only thing you really want to do is create
indexes that will prove useful for often used filters in the application.
[Link]([
{
status: 'Open',
owner: 'Ravan',
created: new Date('2016-08-15'),
effort: 5,
completionDate: undefined,
title: 'Error in console when clicking Add',
},
{
status: 'Assigned',
owner: 'Eddie',
created: new Date('2016-08-16'),
effort: 14,
completionDate: new Date('2016-08-30'),
title: 'Missing bottom border on panel',
},
]);
[Link]({ status: 1 });
[Link]({ owner: 1 });
[Link]({ created: 1 });
Run this script from the command line like this:
$ mongo scripts/[Link]
It should run without any errors. To check the effect of the script, open up the
mongo shell, list all documents using find(), and list all indexes using getIndexes().
The find() should return the two documents that you inserted, with auto-generated
ObjectIDs in the _id field. And, getIndexes() should list four indexes: the three that we
created on status, owner, and created, and the auto-created index on _id.
What is createIndex?
In MongoDB, indexes make searching or querying faster — like an index in a book .
The command createIndex() manually creates an index on one or more fields.
Syntax:
[Link]({ fieldName: 1 })
1 → Ascending order
-1 → Descending order
1. Create an index
[Link]({ email: 1 })
Meaning:
on the email field in ascending order.
Now, when you search by email, MongoDB will find it much faster.
2. Index on multiple fields (compound index):
[Link]({ firstName: 1, lastName: 1 })
Meaning:
Optimize searches by firstName and then lastName.
3. Unique Index (no duplicate values allowed):
[Link]({ username: 1 }, { unique: true })
Meaning:
Each username must be different.
4. Text Index (for text search):
[Link]({ title: "text", body: "text" })
Meaning:
Enable full-text search in title and body.
5. TTL Index (auto-delete documents after some time):
[Link](
{ "createdAt": 1 },
{ expireAfterSeconds: 3600 } // 1 hour
)Meaning:Session documents will auto-delete after 1 hour.
6. View All Indexes on a Collection:
[Link]()
MongoDB itself is schemaless, but Mongoose helps you define a schema to structure your data
properly.
Basic Steps for Schema Initialization with Example:
1. Install Mongoose
npm install mongoose
2. Connect to MongoDB
const mongoose = require('mongoose');
[Link]('mongodb://[Link]:27017/mydb')
.then(() => [Link]('MongoDB connected'))
.catch(err => [Link]('Connection error', err));
3. Define a Schema
const { Schema, model } = mongoose;
const userSchema = new Schema({
name: {
type: String,
required: true
},
age: Number,
email: {
type: String,
unique: true
},
createdAt: {
type: Date,
default: [Link]
}
});Here we defined a User schema with name, age, email, and createdAt fields.
4. Create a Model
const User = model('User', userSchema);
This User model will allow you to interact with the users collection.
5. Save a Document (Insert)
const newUser = new User({
name: 'John Doe',
age: 25,
email: 'john@[Link]'
});
[Link]()
.then(user => [Link]('User saved:', user))
.catch(err => [Link]('Error saving user:', err));
This saves a new user into your database.
Full Example Together:
const mongoose = require('mongoose');
// Step 1: Connect
[Link]('mongodb://[Link]:27017/mydb')
.then(() => [Link]('MongoDB connected'))
.catch(err => [Link]('Connection error', err));
// Step 2: Define Schema
const { Schema, model } = mongoose;
const userSchema = new Schema({
name: { type: String, required: true },
age: Number,
email: { type: String, unique: true },
createdAt: { type: Date, default: [Link] }
});
// Step 3: Create Model
const User = model('User', userSchema);
// Step 4: Create and Save Document
const newUser = new User({
name: 'John Doe',
age: 25,
email: 'john@[Link]'
});
[Link]()
.then(user => [Link]('User saved:', user))
.catch(err => [Link]('Error saving user:', err));
Notes:
required: true → Field must be present.
unique: true → Value must be unique across documents.
default: [Link] → Auto-set current date if not provided.
Aggregation Pipelines
Aggregation operations allow you to group, sort, perform calculations, analyze data, and much
[Link] pipelines can have one or more "stages". The order of these stages are important.
Each stage acts upon the results of the previous stage.
1. $match
Filters documents like a "where" clause.
[Link]([
{ $match: { status: "pending" } }
])
Meaning: Get only the orders where status is "pending".
2. $group
Groups documents by a field and can apply operations like sum, avg, etc.
[Link]([
{
$group: {
_id: "$customerId",
totalAmount: { $sum: "$amount" }
}
}
])
Meaning: Group orders by customerId and calculate total amount for each customer.
3. $project
Change or reshape the documents, like selecting specific fields.
[Link]([
{
$project: {
name: 1,
email: 1,
_id: 0
}
}
])
Meaning: Only show name and email, hide _id.
4. $sort
Sort documents by a field.
[Link]([
{ $sort: { price: -1 } } // -1 means descending
])
Meaning: Sort products by price from highest to lowest.
5. $limit
Limit the number of documents.
[Link]([
{ $limit: 5 }
])
Meaning: Only get the top 5 products.
6. $skip
Skip a certain number of documents (used for pagination).
[Link]([
{ $skip: 10 }
])
Meaning: Skip the first 10 products.
7. $lookup
Join documents from another collection (like SQL join).
[Link]([
{
$lookup: {
from: "customers",
localField: "customerId",
foreignField: "_id",
as: "customerDetails"
}
}
])
Meaning: Attach customer info to each order.
8. $unwind
Deconstruct an array field into multiple documents.
[Link]([
{ $unwind: "$items" }
])
Meaning: Each item in an item array becomes its own document.
9. $count
Counts the number of documents.
[Link]([
{ $count: "totalUsers" }
])
Meaning: Return the total number of users.
10. $addFields
Add new fields or modify existing ones.
[Link]([
{
$addFields: {
discountedPrice: { $multiply: ["$price", 0.9] }
}
}
])
Meaning: Add a discountedPrice field (90% of price).
MongoDB [Link] Driver
A driver is like a bridge between your [Link] app and the MongoDB database.
● It connects [Link] to MongoDB.
● It lets you send commands (like find, insert, update) from [Link] to MongoDB.
● It speaks the MongoDB language internally (BSON, queries, etc.).
1. Install Required Packages
*First, create a folder and initialize [Link]:
mkdir my-mongo-server
cd my-mongo-server
npm init -y
*Install Express (for server) and Mongoose (for MongoDB):
npm install express mongoose
2. Create the [Link] Server (write schema initialization example) or below one
Create a file called [Link]:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const PORT = 3000;
// Middleware to parse JSON
[Link]([Link]());
// Connect to MongoDB
[Link]('mongodb://[Link]:27017/mydb', {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => [Link](' MongoDB Connected'))
.catch(err => [Link]('MongoDB Connection Error:', err));
// Define a simple schema and model
const userSchema = new [Link]({
name: String,
email: String
});
const User = [Link]('User', userSchema);
// Simple route to create a user
[Link]('/users', async (req, res) => {
try {
const { name, email } = [Link];
const user = new User({ name, email });
await [Link]();
[Link](201).json(user);
} catch (err) {
[Link](400).json({ error: [Link] });
}
});
// Simple route to get all users
[Link]('/users', async (req, res) => {
const users = await [Link]();
[Link](users);
});
// Start the server
[Link](PORT, () => {
[Link](` Server running on [Link]
});
3. Folder Structure (simple)
my-mongo-server/
│
├── [Link]
├── [Link]
└── node_modules/
4. Run the Server
node [Link]
If everything is correct, you’ll see:
Server running on [Link]
Callbacks
Old-school style: You pass a function that gets called when the operation finishes.
Example using MongoDB Driver:
const { MongoClient } = require('mongodb');
[Link]('mongodb://[Link]:27017', function(err, client) {
if (err) {
[Link]('Connection failed', err);
return;
}
[Link]('Connected');
const db = [Link]('mydb');
[Link]('users').find().toArray(function(err, users) {
if (err) throw err;
[Link](' Users:', users);
[Link]();
});
});
Callback functions are passed to handle the result or errors.
Problem: Callback Hell (nested callbacks — hard to read)
Promises
Modern style: Operations return a promise, you can use .then() and .catch().
const { MongoClient } = require('mongodb');
[Link]('mongodb://[Link]:27017')
.then(client => {
[Link]('Connected');
const db = [Link]('mydb');
return [Link]('users').find().toArray()
.then(users => {
[Link](' Users:', users);
[Link]();
});
})
.catch(err => {
[Link]('Error:', err);
});
Promises make the code cleaner, and you can chain operations.
Generator Functions + co module
Generators pause and resume execution using yield.
🔹co module lets you write asynchronous code that looks synchronous.
First install co:
🔹
npm install co
Example:
const { MongoClient } = require('mongodb');
const co = require('co');
co(function* () {
const client = yield [Link]('mongodb://[Link]:27017');
[Link](' Connected');
const db = [Link]('mydb');
const users = yield [Link]('users').find().toArray();
[Link]('Users:', users);
[Link]();
}).catch(err => {
[Link]('Error:', err);
});
co + generators make code flow like normal try-catch — but still asynchronous!
Note: co was very popular before async/await became native.
Async/Await
Latest and best way: Clean, simple, looks like synchronous code! The results
are passed through as a waterfall from one function to the next, that is, the outputs of one
are passed to the [Link] all the driver methods follow the same callback convention of error
and results,it’s easy to pass the callbacks through the waterfall. function testWithAsync() {
const async = require('async');
let db;
[Link]([
next => {
[Link]('mongodb://localhost/playground', next);
},
(connection, next) => {
db = connection;
[Link]('employees').insertOne({id: 1, name: 'D. Async'}, next);
},
(insertResult, next) => {
[Link]('Insert result:', [Link]);
[Link]('employees').find({id: 1}).toArray(next);
},
(docs, next) => {
[Link]('Result of find:', docs);
[Link]();
next(null, 'All done');
}
], (err, result) => {
if (err)
[Link]('ERROR', err);
else
[Link](result);
});
}
Reading from MongoDB ([Link] Driver)
✅
There are a few ways to read (or query) documents from a MongoDB collection:
✅ Using findOne() — to get one document
Using find() — to get many documents
Basic Example
const { MongoClient } = require('mongodb');
async function readData() {
const client = new MongoClient('mongodb://[Link]:27017');
try {
await [Link](); //await is a JavaScript keyword used inside async functions to pause the
execution until a Promise resolves — either successfully or with an error.
[Link](' Connected to MongoDB');
const db = [Link]('mydb');
const usersCollection = [Link]('users');
// 1️⃣ Find one document
const oneUser = await [Link]({ name: 'John Doe' });
[Link]('One User:', oneUser);
// 2️⃣ Find multiple documents
const allUsers = await [Link]({}).toArray();
[Link]('All Users:', allUsers);
} catch (error) {
[Link](' Error reading data:', error);
} finally {
await [Link]();
}
}
readData();
Function Purpose
findOne(query) Reads one document matching the query.
find(query).toArray() Reads all documents matching the query and returns an array.
Read with Conditions (Filters)
Suppose you want only users with age > 25:
const usersAbove25 = await [Link]({ age: { $gt: 25 } }).toArray();
[Link](' Users above 25:', usersAbove25);
MongoDB Query Operators:
Operator Meaning
$gt greater than
$lt less than
$eq equal to
$ne not equal
$in in array
Read Only Specific Fields (Projection)
If you want only name and email, not everything:
const userData = await [Link]({}, { projection: { name: 1, email: 1 } }).toArray();
[Link]('Only name and email:', userData);
Method Use
findOne({field: value}) Find single document
find({field: value}).toArray() Find multiple documents
projection Return only selected fields
Writing to MongoDB (Insert Documents)
✅
In MongoDB, writing means inserting documents into a collection.
✅ Use insertOne() → to insert a single document
Use insertMany() → to insert multiple documents
Basic Example ([Link])
const { MongoClient } = require('mongodb');
async function writeData() {
const client = new MongoClient('mongodb://[Link]:27017');
try {
await [Link]();
[Link](‘ Connected to MongoDB');
const db = [Link]('mydb');
const usersCollection = [Link]('users');
// 1️⃣ Insert One Document
const newUser = { name: 'John Doe', email: 'john@[Link]', age: 30 };
const resultOne = await [Link](newUser);
[Link]('Inserted One ID:', [Link]);
// 2️⃣ Insert Multiple Documents
const newUsers = [
{ name: 'Jane Smith', email: 'jane@[Link]', age: 25 },
{ name: 'Mike Johnson', email: 'mike@[Link]', age: 35 }
];
const resultMany = await [Link](newUsers);
[Link]('Inserted Many IDs:', [Link]);
} catch (error) {
[Link](' Error inserting data:', error);
} finally {
await [Link]();
}
}
✨ Quick Explanation:
writeData();
Function Purpose
insertOne({}) Insert one document
insertMany([{}, {}, ...]) Insert multiple documents
✅ After inserting, you can get back the inserted IDs.
Handle Duplicate Key Error (Unique Index)
If you set a field like email to be unique, and insert a duplicate:
await [Link]({ email: 'john@[Link]' });
MongoDB automatically creates a field _id for every document you insert
(unless you provide your own).
Example inserted doc:
{
"_id": "some_random_id",
"name": "John Doe",
"email": "john@[Link]",
"age": 30
}
Method Description
insertOne(doc) Insert a single
document
insertMany([doc1, Insert multiple
doc2]) documents
Modularization
● Breaking your code into smaller, reusable modules/files.
● Each module has a specific responsibility (like a function, API route, DB model, UI
🔹 Benefits:
component, etc.).
● Cleaner and more maintainable code.
● Easy to debug, test, and reuse.
● Better organization in large project
We’re taking a short break from building features and instead focusing on how to organize
your project better as it grows.
We want to:
1. Split code into multiple files (both on backend and frontend).
2. Auto-restart the server or auto-refresh the browser when code changes.
3. Write cleaner code by checking for issues early (with tools like linters).
🧩 Server-Side Modules
Instead of keeping all code in one file, it's better to split different parts into their own files.
For example:
● All "Issue" related logic goes in a file called [Link].
● Your main server code stays in [Link].
How to create your own module
In [Link], you can create a module (reusable code file) like this:
1. Write a function
function sayHello() {
return "Hello!";
}
2. Export it from the file
[Link] = {
sayHello: sayHello
};
Now this file can be imported in another file using require.
Example
You had some validation code for issues (like checking if status is valid or if required fields are
filled). You moved this code into a new file called [Link] like this:
server/[Link]
'use strict'; // Ensures newer JavaScript rules apply (e.g., const)
const validIssueStatus = {
New: true,
Open: true,
Assigned: true,
Fixed: true,
Verified: true,
Closed: true,
};
const issueFieldType = {
status: 'required',
owner: 'required',
effort: 'optional',
created: 'required',
completionDate: 'optional',
title: 'required',
};
function validateIssue(issue) {
for (const field in issueFieldType) {
const type = issueFieldType[field];
if (!type) {
delete issue[field];
} else if (type === 'required' && !issue[field]) {
return `${field} is required.`;
}
}
if (!validIssueStatus[[Link]])
return `${[Link]} is not a valid status.`;
return null;
}
[Link] = {
validateIssue: validateIssue,
};
This function checks:
● Are all required fields present?
● Is the issue status one of the allowed ones?
Using the Module in Your Server
You now import that file in [Link] like this:
const Issue = require('./[Link]');
And later you use:
const err = [Link](newIssue);
That’s how you organize logic into modules — cleaner and reusable!
Organizing Your Project
You moved your server code into a server/ folder, like this:
project/
│
├── server/
│ ├── [Link]
│ └── [Link]
Why?
● Keeps files clean.
● Easy to find related code.
● Makes it more "real project"-like.
Auto-Restart with nodemon
You use nodemon to restart your server automatically when code changes.
You updated [Link] so it watches the whole server/ folder, not just one file:
"scripts": {
"start": "nodemon -w server server/[Link]"
}
Now when you run:
npm start
It watches for any change in server/ and restarts the server automatically.
Back-End Modules ([Link])
These are modules used on the server side — the part of your app that runs in [Link] (not the
browser).
Why use back-end modules?
● Keep server logic organized
● Easier to read and maintain
● Reuse validation, database, or helper logic
Example Setup:
project/
├── server/
│ ├── [Link] // main server entry
│ └── [Link] // custom module for issue validation
[Link] (your custom module):
'use strict'; // Needed for using const, let safely in older Node versions
function validateIssue(issue) {
if (![Link]) return "Title is required";
return null;
}
[Link] = {
validateIssue,
};
[Link] (main server file):
const express = require('express');
const Issue = require('./issue'); // ← your custom module
const app = express();
[Link]([Link]());
[Link]('/api/issues', (req, res) => {
const newIssue = [Link];
const error = [Link](newIssue);
if (error) return [Link](400).send({ message: error });
// Save to DB (pseudo-code)
[Link]({ success: true });
});
Front-End Modules (Browser Side using Webpack)
These are modules used in the client side — the part of your app that runs in the browser (like
React components, UI logic, CSS).
Why use front-end modules?
● Separate UI into reusable pieces
● Maintain CSS/JS independently
● Enable hot reloads, tree-shaking, bundling
Example Setup:
project/
├── src/
│ ├── [Link] // main entry point
│ ├── components/
│ │ └── [Link] // reusable React component
components/[Link]:
import React from 'react';
export default function Header() {
return <h1>Welcome to the Issue Tracker</h1>;
}
[Link] (entry point):
import React from 'react';
import ReactDOM from 'react-dom';
import Header from './components/Header';
[Link](<Header />, [Link]('root'));
🔧 Webpack setup:
// [Link]
const path = require('path');
[Link] = {
entry: './src/[Link]',
output: {
path: [Link](__dirname, 'dist'),
filename: '[Link]'
},
module: {
rules: [
{
test: /\.js$/, // Transpile JS files using Babel
exclude: /node_modules/,
use: 'babel-loader',
}
]
},
devServer: {
static: './dist',
hot: true
},
mode: 'development'
};
🚀 Run Frontend Dev Server:
npx webpack serve
This will:
● Watch your files for changes
● Re-bundle code
● Auto-refresh browser (with Hot Module Replacement)
✅ Summary Table
Feature Back-End Modules Front-End Modules
Language [Link] (CommonJS) JavaScript (ES6 Modules with
Babel/Webpack)
Module require('./file') import x from './file'
Import
Export [Link] export default / export {}
Purpose Organizeservercode(routes, OrganizeUIcode (React, styles, logic)
validation, DB)
Tools [Link], Express, Nodemon Webpack, Babel, React, Hot Reload
Example [Link] for validation [Link] for UI
Webpack
Traditionally, to use JavaScript in a webpage, we used many <script> tags in the HTML file —
🔻
one for each JS file.
The problem:
● You have to manually manage the order of files
● Too many <script> tags becomes messy
👉 ● Doesn’t handle modern JS features (like imports, JSX, etc.)
Webpack solves this!
What Webpack Does:
● Joins all your JS files (and even CSS/images if you want) into 1 file
● That one file (called a bundle) is easy to include in your HTML
● It also transforms modern JS (like JSX or ES6) to plain JS using tools like Babel
Why We Need Webpack in Our Project
We're splitting our React app into multiple small files (components) to keep code organized.
Webpack lets us:
● Use import/export
● Bundle everything into one file
● Watch for changes automatically during development
🧪 Installing Webpack
Run this in your project folder:
npm install webpack
Creating Your First Webpack Bundle
Imagine you have a main React file: static/[Link]
You can bundle it using this command:
node_modules/.bin/webpack static/[Link] static/[Link]
This creates [Link] — which contains all code from [Link] and anything [Link] imported!
🧩 Splitting Code into Modules
Let’s say [Link] contains everything. Now you want to separate one component, like IssueAdd,
into its own file.
1. Create [Link]
import React from 'react';
export default class IssueAdd extends [Link] {
// your form logic here
}
2. Use it in [Link]
import IssueAdd from './[Link]'; // ← this pulls in the component
class App extends [Link] {
render() {
return <IssueAdd />;
}
}
Webpack sees this import, follows it, and includes IssueAdd in the final bundle —
automatically.
Compiling JSX
npm run compile
You’ll now have:
● [Link]
● [Link]
Webpack bundles both into [Link]
🧾 Output After Bundling
When you run webpack, it says something like:
[Link] 11.7 kB [built]
[0] ./static/[Link]
[1] ./static/[Link]
This means:
● Webpack read your files
● Figured out the dependencies from import statements
● Created one file: [Link] that has all your code
🖥️ Update Your HTML File
Change your [Link] file to use the bundle:
html
<!-- Before -->
<script src="/[Link]"></script>
<!-- After -->
<script src="/[Link]"></script>
Now your browser only loads one script, and it includes everything your app needs.
🧹 Clean Up
You may delete the old [Link] and [Link] in your static folder — the browser doesn’t need
them anymore, only the final [Link]
Hot Module Replacement(HMR)
What's the Problem Without HMR?
When you're building a website or app and you change something — say a button color, or a bit
of text — you usually need to refresh your browser to see the change. This works, but it can be
slow and annoying, especially because:
● You lose what you were doing in the app (like typed form data).
● You might refresh too early, and the old version gets loaded.
● Waiting for a full rebuild every time is time-consuming.
When you change something in your code:
Instead of refreshing the entire page…HMR just swaps out only the changed parts of your
[Link] app stays right where it is, with no reset, and updates instantly.
🚗
It's like changing the tires on a car while it's still moving — no full stop required!
How Do You Use HMR?
There are two main ways to use HMR:
✅ Option 1: webpack-dev-server
Think of webpack-dev-server like a temporary developer-only server that:
● Watch your files.
● Serves your app directly from memory (faster!).
● Automatically updates your browser when something changes.
How it works:
You run:
npm run watch # or use the long command with --hot
1. It serves your app on a special port like [Link]
2. You open that page and start developing.
3. Change some code — it auto-updates in the browser, no reload needed.
You can also tell it to send API requests to your Express server (running on port 3000) using a
"proxy", so everything still works like one big happy app.
Example HMR log in browser console:
[HMR] Waiting for an update signal from WDS...
[WDS] Hot Module Replacement enabled.
✅ Option 2: HMR via Express Middleware
This is a more integrated way where you don't use two ports or two servers.
Instead, you:
● Use your existing Express server (localhost:3000) for everything.
● Plug in some middleware tools (webpack-dev-middleware and
webpack-hot-middleware).
● Let Express handle both:
○ Your backend API
○ Your frontend HMR updates
This means only one terminal, one browser tab, and no mix-ups.
But there's a catch:
● Every time the server code changes, the frontend rebuilds too — and that's slow.
🤔 So Which One Should You Use?
● If you mostly work on frontend, this can be annoying.
Feature webpack-dev-server Middleware in Express
✅ Easy setup ✔️ ❌ More involved
🔁 Fast client-side updates ✔️ ✔️
🌐 Single port (one server) ❌ (8000 + 3000) ✔️
🧱 Rebuilds on backend changes ❌ ❌ But happens anyway
💻 Better if mostly front-end ✔️ 👎
👉 Most people prefer webpack-dev-server during development because:
● It's fast.
● It doesn't rebuild for no reason.
● It's reliable.
Debugging
Imagine you're building a car.
● In the garage (development), you want all your tools, sensors, and detailed error
messages nearby — so if something breaks, you can fix it quickly.
● On the road (production), you want a smooth, lightweight car — no toolbox in the
trunk, no blinking error logs.
In coding terms:
● Development build: Includes extra code that helps you find bugs (like [Link],
error messages, line numbers).
● Production build: Strip all that out to make the app smaller and faster.
DefinePlugin: Setting Global Constants
What is it?
The DefinePlugin is a tool in Webpack that lets you create global constants your app can use
— like telling your code:
"Hey, we're in development mode!" or
"Hey, this is production — don’t show debug info!"
Example:
new [Link]({
'[Link].NODE_ENV': [Link]([Link].NODE_ENV)
})
This sets a global constant [Link].NODE_ENV that your code can use to do things like:
if ([Link].NODE_ENV !== 'production') {
[Link]('Debug mode on!');
}
So when you run:
NODE_ENV=production npm run build
Your app knows it's in production, and removes the debug logs automatically during the build.
Build Configuration: Switching Modes
Webpack has two main modes:
Mode What it does
development Adds tools for
debugging
production Optimizes the app for
users
In your [Link], you can set:
mode: [Link].NODE_ENV || 'development',
Now depending on how you run the command (NODE_ENV=production), it behaves
differently!
Production Optimization: Make it Faster for Users
Once your app is ready for real users, you want to make it:
● Smaller in file size
● Faster to load
● Free of debug code
Webpack helps with this by doing things like:
● Minifying your JavaScript (removing spaces, shortening variable names)
● Removing console logs (if you used DefinePlugin properly)
● Compressing images and assets
● Splitting large code into smaller chunks (called "code splitting")
So in summary:
Area Development Production
Debugging Lots of logs, helpful messages Stripped out
File size Bigger, easier to trace Smaller, optimized
Console output Includes [Link]() Usually removed
Speed Slower builds, but easier to debug Faster app for real users