Full Stack Development Bis601: Module 1: Javascript Basics
Full Stack Development Bis601: Module 1: Javascript Basics
2. String: Represents textual data, enclosed in single quotes, double quotes, or backticks (template
literals).
let name = "Alice"; // Double quotes
let greeting = 'Hello!'; // Single quotes
let message = `My name is ${name}.`; // Template literal
3. Boolean: Represents a logical entity and can only have two values: true or false.
let isActive = true;
let hasPermission = false;
4. Undefined: Indicates that a variable has been declared but has not yet been assigned a value.
let myVariable; // myVariable is undefined
5. Null: Represents the intentional absence of any object value. It's a primitive value.
let emptyValue = null;
6. Symbol: Introduced in ES6, it represents a unique and immutable value, often used as object
property keys to avoid naming collisions.
const id = Symbol('uniqueId');
7. BigInt: Introduced in ES2020, it represents integers with arbitrary precision, allowing for
numbers larger than the maximum safe integer for Number.
JavaScript
let bigNumber = 9007199254740991n; // The 'n' indicates a BigInt
Q.2 Write a JavaScript program using loops and conditions to print prime numbers
between 1 and 100.
The scope of a varvariable is The scope of alet variable is The scope of a const variable is
functional or global scope. block scope. block scope.
These variables are hoisted but These variables are hoisted but
These variables are hoisted. stay in the temporal dead zone stays in the temporal dead
untill the initialization. zone until the initialization.
console.log(sortedFruits);
Q.5 What are JavaScript objects? Create a custom object and demonstrate object
methods.
JavaScript objects are non-primitive data types used to store collections of data as key-value pairs. These
pairs consist of properties (variables) and methods (functions) that define the object's characteristics and
behaviors. Objects are fundamental building blocks in JavaScript, allowing for the organization and
encapsulation of related data and functionality.
startEngine: function() {
console.log("The engine is starting...");
},
displayInfo: function() {
console.log(`Make: ${this.make}, Model: ${this.model}, Year: ${this.year}`);
}
};
console.log(Car.make);
Car.startEngine();
Car.displayInfo();
Q.6 Write a program to demonstrate string operations like slicing, concatenation, and
replacement
// Original strings
let str1 = "Hello";
let str2 = "World";
// 1. Concatenation
let fullStr = str1 + " " + str2;
console.log("Concatenation:", fullStr); // Output: Hello World
// 3. Replacement
let replaced = fullStr.replace("World", "JavaScript");
console.log("After Replacement:", replaced); // Output: Hello JavaScript
Q.7 Discuss the role and syntax of comments, statements, and expressions in JavaScript
In JavaScript, comments, statements, and expressions serve distinct roles in code organization, execution,
and value generation.
1. Comments:
Comments are non-executable parts of the code used to provide explanations, documentation, or temporarily
disable code sections. They are ignored by the JavaScript engine during execution.
Syntax:
Single-line comments: Begin with //. All text from // to the end of the line is a comment.
// This is a single-line comment
let x = 10; // Assigning a value to x
Multi-line (block) comments: Begin with /* and end with */. All text between these delimiters, spanning
multiple lines, is a comment.
/*
This is a multi-line comment.
It can span across several lines
to provide detailed explanations.
*/
2. Statements:
Statements are instructions that perform an action. They represent a complete unit of execution in
JavaScript.
Syntax:
Statements typically end with a semicolon (;), although in many cases, Automatic Semicolon Insertion (ASI)
can infer them.
let name = "John"; // Variable declaration and assignment statement
console.log(name); // Function call statement
if (true) { // Conditional statement
// ...
}
for (let i = 0; i < 5; i++) { // Loop statement
// ...
}
3. Expressions:
Expressions are combinations of values, variables, and operators that evaluate to a single value. They can be
part of a larger statement.
Syntax:
Expressions do not necessarily end with a semicolon unless they also function as a standalone statement.
5 + 3 // An arithmetic expression evaluating to 8
"Hello" + " " + "World" // A string concatenation expression
x > 5 // A comparison expression evaluating to true or false
let result = (a * b) / c; // The part (a * b) / c is an expression
Q.8 Design a calculator program that uses functions to perform basic operations (+, –,
×, ÷).
Q.1 Explain the Document Object Model (DOM) and its tree structure
The Document Object Model (DOM) is a programming interface that represents an HTML or XML
document as a tree structure, allowing scripts (like JavaScript) to dynamically access and manipulate the
document's content, structure, and style. In essence, the DOM treats each part of a webpage as a node in a
tree, enabling developers to interact with and modify the page's elements.
<!DOCTYPE html>
<html>
<head>
<title>Dynamic Content</title>
</head>
<body>
<h1 id="greeting">Hello!</h1>
<button onclick="changeContent()">Click Me</button>
<script>
function changeContent() {
const heading = document.getElementById("greeting");
heading.textContent = "Welcome to JavaScript DOM!";
}
</script>
</body>
</html>
Q.3 What are event listeners? Create an example using addEventListener() for a button
click.
In JavaScript, event listeners are functions that wait for user interactions like clicks, key presses, mouse
moves, etc., and then execute code in response.
Using addEventListener(), we can attach multiple actions to a single element and separate JavaScript
from HTML — keeping code clean and organized.
<!DOCTYPE html>
<html>
<head>
<title>Event Listener Example</title>
</head>
<body>
<button id="myButton">Click Me</button>
<p id="message">Initial message</p>
<script>
const button = document.getElementById("myButton");
const message = document.getElementById("message");
button.addEventListener("click", function() {
message.textContent = "You clicked the button!";
});
</script>
</body>
</html>
Q.4 Describe the differences between event delegation and direct event binding.
Number of One listener per element One listener for multiple elements
Listeners
Dynamic Requires re-binding for new elements Handles new elements automatically through
Content bubbling
Performance Can be less efficient with many More efficient with many elements and dynamic
elements content
Code Clarity Can be more verbose with many Can be more concise with many elements
elements
Advantages Simplicity , Precise Targeting, Less Memory Usage , Performance Boost , Works
Better for Non-Bubbling Events with Dynamic Elements, Easier Maintenance
Disadvantages Doesn't Handle Dynamic Elements, More Complex Logic, Not Suitable for All Events,
Scalability Problems, Memory Usage Unexpected Behavior
click: Occurs when the user clicks an element. For example, if a button is clicked, the click
event will fire.
mouseover / mouseout: Fires when the mouse cursor enters or leaves the boundaries of an
element, respectively.
mousedown / mouseup: Fired when the mouse button is pressed down or released over an
element.
mousemove: Fired when the mouse is moved over an element.
contextmenu: Fires when the user right-clicks on an element, typically opening a context
menu.
Ex: document.getElementById("btn").addEventListener("click", function() {
alert("Button clicked!");
});
2. Keyboard Events:
keydown / keyup: Triggered when a key is pressed down or released, respectively.
Ex: document.addEventListener("keydown", function(event) {
console.log("Key pressed:", event.key);
});
3. Form Events:
submit: Fired when a form is submitted (e.g., by clicking a submit button).
focus / blur: Fired when an element gains or loses focus, respectively (e.g., when a user
clicks inside or outside an input field).
change: Fires when the value of an element (like an input field) is changed.
Ex: document.querySelector("form").addEventListener("submit", function(e) {
e.preventDefault();
alert("Form submitted!");
});
4. Window Events:
load: Fires when the entire page (including all resources like images) has finished loading.
DOMContentLoaded: Fires when the HTML document has been completely loaded and
parsed, but external resources might still be loading.
resize: Fires when the browser window is resized.
scroll: Fires when the document is scrolled.
hashchange: Fires when the URL's fragment identifier (the part after the #) has changed.
unload: Fires when the user is navigating away from the page (e.g., closing the tab or
navigating to a different page).
Ex: window.addEventListener("resize", function() {
console.log("Window resized!");
});
Q.7 Implement a script that changes the background color of a page on a mouseover
event
To change the background color of a page on a mouseover event using JavaScript, you can
use the onmouseover event and the document.body.style.backgroundColor property.
<!DOCTYPE html>
<html>
<head>
<title>Background Color Changer</title>
</head>
<body onmouseover="changeBackgroundColor('red')"
onmouseout="changeBackgroundColor('white')">
<h1>Move your mouse over me</h1>
<p>This page's background color will change when you move your mouse over it.</p>
<script>
function changeBackgroundColor(color) {
document.body.style.backgroundColor = color;
}
</script>
</body>
</html>
Q.8 Write code that listens for keyboard input and logs the key pressed
<!DOCTYPE html>
<html>
<head>
<title>Key Logger</title>
</head>
<body>
<h2>Press any key</h2>
<div id="output"></div>
<script>
const output = document.getElementById('output');
document.addEventListener('keydown', (e) => {
output.innerHTML = `
Key: <b>${e.key}</b><br>
Code: ${e.code}<br>
Ctrl: ${e.ctrlKey ? 'Yes' : 'No'}<br>
Shift: ${e.shiftKey ? 'Yes' : 'No'}
`;
console.log('Pressed:', e.key);
});
</script>
</body>
</html>
The MERN stack is a popular JavaScript-based web development framework for building dynamic and
scalable web applications. It consists of four key technologies: MongoDB, Express.js, React, and
Node.js. MongoDB is the database, Express.js is the backend framework, React is the frontend library, and
Node.js provides the runtime environment for the backend.
This Keyword Does not use this keyword Uses this to access props and state
Code Less boilerplate code, easier More boilerplate code, especially for state
Complexity to write and understand and methods
Feature Functional Components Class Components
Event Simple and direct event Requires method binding for event
Handling handling handling
Q.5 Create a simple issue tracker using component composition and static data.
Issue.js :
return (
<div style={{ padding: '20px', fontFamily: 'Arial' }}>
<h1>� Issue Tracker</h1>
<IssueTracker issues={issues} />
</div>
);
};
export default App;
IssueTracker.js :
IssueItem.js:
return (
<div style={{
border: '1px solid #ccc',
padding: '10px',
margin: '8px 0',
borderRadius: '5px'
}}>
<h3>{title}</h3>
<p>Status: <span style={{ color }}>{status}</span></p>
</div>
);
};
Q.6 What are children props? Demonstrate passing data using children.
In React, children is a special prop that allows you to pass components or elements as content to other
components, effectively nesting structures and enabling component composition. This special prop allows
for creating more flexible and reusable components, where the parent component can define the structure
while the child component provides the specific content.
// Parent Component
function ParentComponent({ children }) {
return (
<div style={{ border: '1px solid black', padding: '10px' }}>
{children}
</div>
);
}
// Child Component
function MyComponent({ text }) {
return <p>{text}</p>;
}
// Usage
function App() {
return (
<ParentComponent>
<MyComponent text="This is some content from the child." />
<p>This is some text passed directly.</p>
</ParentComponent>
);
}
Q.7 Design a React component that conditionally renders content based on a boolean
prop.
A React component can conditionally render content based on a boolean prop using various methods,
including the ternary operator, logical AND operator, or an if statement.
i. Ternary Operator:
iii. if statement:
import React from 'react';
function ComplexConditionalContent({ isLoggedIn, isAdmin }) {
if (isLoggedIn && isAdmin) {
return <p>Welcome, Admin!</p>;
} else if (isLoggedIn) {
return <p>Welcome, User!</p>;
} else {
return <p>Please log in.</p>;
}
}
export default ComplexConditionalContent;
Q.8 Write a Hello World MERN setup explanation with a minimal code base
Here's a minimal ―Hello World‖ MERN stack setup explained simply — with just enough to
show how all four parts (MongoDB, Express, React, Node.js) work together.
a. index.js:
b. client.js:
import React, { useEffect, useState } from 'react';
function App() {
const [msg, setMsg] = useState('');
useEffect(() => {
fetch('http://localhost:5000/api/hello')
.then(res => res.json())
.then(data => setMsg(data.message));
}, []);
return (
<div style={{ fontFamily: 'Arial', padding: '20px' }}>
<h1>� MERN Hello World</h1>
<p>{msg}</p>
</div>
);
}
Connect MongoDB:
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/helloDB')
.then(() => console.log("MongoDB connected"))
.catch(err => console.log(err));
Module 4: React State & API (Express, GraphQL)
Q.1 Define React state and explain how to initialize and update it.
In React, state is a JavaScript object that holds data specific to a component, which can change over time
and influence the component's rendering. When the state of a component changes, React automatically re-
renders that component and its children to reflect the updated data in the UI. This makes React components
dynamic and responsive to user interactions or data updates.
Initializing State:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
}
Updating State:
setCount(count + 1);
Q.2 Implement a React component using useState and useEffect for counter behavior.
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`Counter updated: ${count}`);
document.title = `Count: ${count}`;
}, [count]);
return (
<div style={{ fontFamily: 'Arial', textAlign: 'center', marginTop: '50px' }}>
<h1>� React Counter</h1>
<p>Current count: {count}</p>
<button onClick={() => setCount(count + 1)} style={{ marginRight: '10px' }}>
Increment
</button>
<button onClick={() => setCount(count - 1)}>
Decrement
</button>
</div>
);
}
"Lifting state up" in React is a pattern used to share state between multiple components that
need to access and potentially modify the same data. Instead of each component managing
its own independent state, the shared state is moved ("lifted") to their closest common
ancestor component. This ancestor then becomes the "single source of truth" for that state.
Concept:
Identify Shared State:
Determine which components require access to the same piece of state data.
Move State to Common Ancestor:
Locate the closest parent component that is an ancestor to all components needing the shared
state. Declare and manage the state within this common ancestor.
Pass State Down as Props:
The common ancestor passes the state values down to its relevant child components as props.
Handle State Changes with Callbacks:
If a child component needs to update the shared state, the common ancestor passes down
callback functions as props. The child component invokes these callbacks, passing the
necessary data, which then allows the common ancestor to update its state.
Example:
A.js
import React, { useState } from 'react';
import NameInput from './NameInput';
import NameDisplay from './NameDisplay';
function App() {
const [name, setName] = useState('');
return (
<div style={{ fontFamily: 'Arial', padding: '20px' }}>
<h1> Lifting State Up Example</h1>
<NameInput name={name} setName={setName} />
<NameDisplay name={name} />
</div>
);
}
export default App;
B.js:
C.js:
import React from 'react';
PROPS STATE
It is Immutable (cannot be
It is Mutable ( can be modified).
modified).
Props can be used with state and The state can be used only with the state
functional components. components/class component (Before 16.0).
A GraphQL Schema serves as a blueprint for the API that defines what data can be queried
from the server, and what are the different types of that data. They define a contract of API
between a server and a client.
Ex:
type Post {
id: ID!
title: String!
content: String!
author: String!
}
type Query {
getPost(id: ID!): Post
listPosts: [Post]
}
type Mutation {
createPost(title: String!, content: String!, author: String!): Post
}
Q.6 Write a sample Express.js REST API to create and fetch product data
A sample Express.js REST API for creating and fetching product data is provided
below. This example uses an in-memory array to simulate a database
app.use(bodyParser.json());
if (!name || !price) {
return res.status(400).json({ message: 'Product name and price are required.' });
}
const newProduct = {
id: nextProductId++,
name,
price,
description: description || '' // Optional description
};
products.push(newProduct);
res.status(201).json(newProduct); // 201 Created
});
if (!product) {
return res.status(404).json({ message: 'Product not found.' }); // 404 Not Found
}
res.status(200).json(product);
});
app.listen(PORT, () => {
console.log(`Product API running on http://localhost:${PORT}`);
});
Q.8 Design an Express API that validates inputs and handles errors gracefully.
a) Validation Middleware:
const validateUser = [
body('username')
. isLength({ min: 3 })
.withMessage('Username must be at least 3 characters long'),
body('email')
.isEmail()
.withMessage('Invalid email address'),
body('password')
.isStrongPassword()
.withMessage('Password is not strong enough'),
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
next();
}
];
Apply to Routes:
b) Propagate Errors:
app.get('/data', async (req, res, next) => {
try {
const data = await fetchDataFromDatabase();
res.json(data);
} catch (error) {
next(error);
}
});
Module 5: MongoDB, Webpack & Modularization
Q.1 Explain the core components of MongoDB: Document, Collection, and Database.
MongoDB - Database, Collection, and Document
Document in MongoDB:
In MongoDB, the data records are stored as BSON documents. Here, BSON stands for
binary representation of JSON documents, although BSON contains more data types as
compared to JSON. The document is created using field-value pairs or key-value
pairs and the value of the field can be of any BSON type.
Syntax:
{
field1: value1
field2: value2
....
fieldN: valueN
}
Document Structure:
A document in MongoDB is a flexible data structure made up of field-value pairs. For
instance:
{
title: "MongoDB Basics",
author: "John Doe",
year: 2025
}
Naming restriction for Document Fields:
Before moving further first you should learn about the naming restrictions for fields:
Fields in documents must be named with strings
The _id field name is reserved to use as a primary key. And the value of this field must
be unique, immutable, and can be of any type other than an array.
The field name cannot contain null characters.
The top-level field names should not start with a dollar sign ($).
Document Size:
The maximum size of the BSON document is 16MB. It ensures that the single document
does not use too much amount of RAM or bandwidth(during transmission). If a document
contains more data than the specified size, then MongoDB provides a GridFS API to store
such type of documents. A single document may contain duplicate fields.
MongoDB always saves the order of the fields in the documents except for the _id field
(which always comes in the first place) and the renaming of fields may change the order
of the fields in the documents.
Collection in MongoDB:
A Collection in MongoDB is similar to a table in relational databases. It holds a group of documents
and is a part of a database. Collections provide structure to data, but like the rest of MongoDB, they
are schema-less.
Schemaless
As we know that MongoDB databases are schemaless. So, it is not necessary in a collection that
the schema of one document is similar to another document. Or in other words, a single collection
contains different types of documents like as shown in the below example
where mystudentData collection contain two different types of documents:
Example:
db.books.insertOne({ title: "Learn MongoDB", author: "Jane Doe", year: 2023 })
Creating collection
After creating database now we create a collection to store documents. The collection is created
using the following syntax:
db.collection_name.insertOne({..})
Database in MongoDB
A Database in MongoDB is a container for data that holds multiple collections. MongoDB allows
the creation of multiple databases on a single server, enabling efficient data organization and
management for various applications. It’s the highest level of structure within
the MongoDB system.
1. Multiple Databases: MongoDB allows you to create multiple databases on a single server. Each
database is logically isolated from others.
2. Default Databases: When you start MongoDB, three default databases are
created: admin, config, and local. These are used for internal purposes.
3. Database Creation: Databases are created when you insert data into them. You can create or
switch to a database using the following command:
use <database_name>
This command actually switches you to the new database if the given name does not exist and if
the given name exists, then it will switch you to the existing database. Now at this stage, if you
use the show command to see the database list where you will find that your new database is not
present in that database list because, in MongoDB, the database is actually created when we start
entering data in that database.
4. View Database: To see how many databases are present in your MongoDB server, write the
following statement in the mongo shell:
show dbs
Naming Restriction for Database:
Before creating a database we should first learn about the naming restrictions for databases:
Database names must be case-insensitive.
The names cannot contain special characters such as /, ., $, *, |, etc.
MongoDB database names cannot contain null characters(in windows, Unix, and Linux systems).
MongoDB database names cannot be empty and must contain less than 64 characters.
Q.2 Write basic MongoDB queries for CRUD operations using Node.js.
Basic MongoDB CRUD (Create, Read, Update, Delete) operations using Node.js with the official mongodb
driver are demonstrated below. These examples assume a connection to a MongoDB instance has already
been established.
1. Create (Insert):
2. Read (Find):
3. Update:
const { MongoClient } = require('mongodb');
4. Delete:
Data modeling in MongoDB involves designing the structure of your documents and collections to
efficiently store and retrieve data. Unlike relational databases, MongoDB offers a flexible schema, allowing
documents within a collection to have varying structures. This flexibility requires careful consideration of
how data will be accessed and updated to optimize performance.
{
"_id": ObjectId("60d5f9..."),
"name": "Wireless Headphones",
"description": "Bluetooth over-ear headphones with noise cancellation",
"price": 299.99,
"inStock": true,
"tags": ["audio", "wireless", "bluetooth"],
"category": {
"id": "123",
"name": "Electronics"
},
"reviews": [
{
"user": "John",
"rating": 5,
"comment": "Great sound quality!"
},
{
"user": "Emma",
"rating": 4,
"comment": "Very comfortable to wear"
}
],
"createdAt": "2025-06-21T10:00:00Z"
}
Q.4 Discuss the role of Mongoose in MERN applications.
Mongoose is an elegant Object Data Modeling (ODM) library for MongoDB and Node.js, serving as a
crucial component in the MERN (MongoDB, Express.js, React, Node.js) stack. It provides a straight-
forward, schema-based solution to model your application data while offering features like validation, query
building, and business logic hooks.
module.exports = router;
Defining a Schema and Model
mongoose.connect('mongodb://localhost:27017/mernshop')
.then(() => {
console.log('MongoDB connected via Mongoose');
app.listen(5000, () => console.log(' Server running on port 5000'));
})
.catch(err => console.error(' Connection error:', err));
Webpack is a static module bundler for JavaScript applications that helps manage and optimize front-end
assets. It takes your application's code, including JavaScript, CSS, images, and other assets, and bundles
them into optimized static files that can be easily loaded by web browsers. Webpack helps developers
organize code, handle dependencies, and improve performance by optimizing assets for faster loading.
Modular JavaScript:
Webpack treats all files as modules and helps manage dependencies between them, allowing
developers to write modular and maintainable code.
Asset Transformation:
Webpack uses loaders to process various asset types (like CSS, images, fonts) and transform
them into modules that can be included in the final bundles.
Dependency Graph:
Webpack builds a dependency graph to understand how different modules are related and
uses this graph to create optimized bundles.
Bundling:
Webpack combines these modules and assets into a smaller number of bundles, reducing the
number of HTTP requests needed to load a web page and improving performance.
Optimization:
Webpack offers various optimizations like code splitting, tree shaking, minification, and
caching to further improve performance and reduce bundle sizes.
Frontend Backend
Involves technologies like HTML, CSS, Involves technologies like PHP, Python, Node.js,
JavaScript, and frameworks Ruby, and databases like MySQL, MongoDB, and
like React, Vue.js, and Angular. PostgreSQL.
The average salary of the Frontend Developer The average salary of the Backend Developer is
is $80,796 $90,652
Work closely with designers, UX/UI Work closely with front-end developers, system
developers, and back-end developers administrators, and database administrators
Deals with UI design, user interaction, and Deals with data processing, server communication,
performance on the client side. and storing/retrieving data from databases.
Frontend developer uses tools to create an The back-end developer builds the server, database,
Frontend Backend
interface and focus on the user experience. and application logic, focusing on the application's
performance.
Front-end developers are in high demand due Back-end developers are also in high demand,
to the increasing emphasis on user experience especially with the growth of data-driven
(UX) and interface design. applications, cloud services, and APIs.
Q.7 Explain Hot Module Replacement (HMR) and its use in development
Hot Module Replacement (HMR) is a development tool that allows you to update parts of your running
application without requiring a full page reload. It provides a faster feedback loop during development by
only updating the changed modules while preserving the application's state. This is especially useful for
large, complex applications where a full reload can be time-consuming and disruptive.
Here's a more detailed explanation:
How it works:
HMR works by identifying the specific modules that have been changed and replacing them in the
running application.
Instead of a complete page refresh, HMR applies these changes dynamically, preserving the
application's current state (e.g., form data, scroll position).
This process is facilitated by module bundlers like Webpack and Vite, which provide the necessary
infrastructure and APIs for HMR to function.
Benefits of HMR:
Faster development cycles:
By eliminating the need for full page reloads, HMR significantly speeds up the development process.
State preservation:
HMR ensures that the application's state is not lost during updates, allowing developers to see
changes in context without having to re-navigate or re-enter data.
Improved developer experience:
The ability to see changes instantly and without disruption makes development more intuitive
and engaging.
Use cases:
Front-end development:
HMR is widely used in front-end development with frameworks like React, Vue, and
Angular, as well as with module bundlers like Webpack and Vite.
Preserves application state: Form inputs, scroll position, and UI state remain intact
Q.8 Write a build configuration using Webpack with DefinePlugin and production
optimization.
const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
'__PRODUCTION__': JSON.stringify(true),
'__API_URL__': JSON.stringify('https://api.yourdomain.com/production'),
}),
],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true,
},
},
}),
new CssMinimizerPlugin(),
],
splitChunks: {
chunks: 'all',
},
runtimeChunk: 'single',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
};