This is a personal blog for referencing the coding programs. Visitors may not find anything else , but boring & unpleasant code programs which I will be posting for my own reference
Spring Boot - Part 3 (Exception Handling,JPA Pagination, Swagger, Deployment)
Get link
Facebook
X
Pinterest
Email
Other Apps
Exception Handling
Exception Handling is the process of intercepting these exceptions before they reach the client and returning a clean meaningful response with the correct HTTP status code instead. In Spring Boot exception handling is done in 3 parts —
Custom exception classes that describe what went wrong,
An error response class that defines what the client receives, and a
Global exception handler that intercepts every exception in your app and returns the right response automatically.
Step 1 — Custom Exception Classes
Right now you are throwing a generic RuntimeException everywhere :
thrownewRuntimeException("User not found"); // ❌ generic, tells nothing
The problem is every error in your app looks the same. You cannot tell a "user not found" error apart from an "email already exists" error. They are both just RuntimeException. The solution is to create specific exception classes for each type of error. Every custom exception just extends RuntimeException and passes a meaningful message :
Now instead of throwing a generic exception you throw a specific one :
thrownewUserNotFoundException(99); // ✅ specific and meaningful
thrownewEmailAlreadyExistsException("a@b.com"); // ✅ specific and meaningful
NOTE : All custom exceptions extend RuntimeException — not Exception. This keeps them unchecked so you do not need try catch blocks everywhere in your service layer.
Step 2 — Error Response Class
Now that you have specific exceptions you need a clean object to send back to the client. Instead of Spring's ugly default error object you create your own :
public String getTimestamp() { return timestamp; }
}
When an error occurs the client will receive this clean JSON :
{
"status":404,
"message":"User with id 99 not found",
"timestamp":"2024-01-15T10:30:00"
}
Step 3 — Global Exception Handler
You have custom exceptions and a clean error response. Now you need something that sits between your app and the client, catches every exception, and returns the right ErrorResponse with the right HTTP status.
This is done using @RestControllerAdvice. It marks a class as a global exception handler — Spring automatically routes all exceptions thrown anywhere in your app to this class. Inside it you define a method for each exception using @ExceptionHandler which tells Spring which specific exception that method handles.
// exception/GlobalExceptionHandler.java
@RestControllerAdvice
publicclassGlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
NOTE : The order of @ExceptionHandler methods matters. Always put the most specific exceptions first and Exception.class last. Spring picks the first matching handler it finds. If you put Exception.class first it will catch everything and your specific handlers will never be called.
NOTE : You only need one GlobalExceptionHandler class in your entire project. It automatically handles exceptions from every controller. Never put exception handling logic inside individual controllers. If you have multiple handlers and two of them handle the same exception Spring does not know which one to use. The behavior becomes unpredictable and hard to debug.
Step 4 — Throwing Custom Exceptions in Service
Now update your service to throw custom exceptions. Any exception throws goes through the global exception handlers and intercepted correctly.
@Service
publicclassUserService {
@Autowired
private UserRepositoryuserRepository;
public User getUserById(intid) {
return userRepository.findById(id)
.orElseThrow(() ->newUserNotFoundException(id));
}
public User createUser(User user) {
if (userRepository.existsByEmail(user.getEmail())) {
ResponseEntity represents the entire HTTP response — the body and the status code. You use it in your controller to return the correct status code with every response. Without it Spring always returns 200 OK even when you create a resource which should be 201 Created :
// if email exists — GlobalExceptionHandler returns 409 automatically
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariableintid) {
userService.deleteUser(id);
return ResponseEntity.noContent().build(); // 204
}
}
## How Everything Flows Together
GET /users/99
↓
UserController.getUserById(99)
↓
UserService.getUserById(99)
↓
userRepository.findById(99) → empty Optional
↓
throws UserNotFoundException("User with id 99 not found")
↓
@RestControllerAdvice intercepts it
↓
@ExceptionHandler(UserNotFoundException.class) is called
↓
Returns :
{
"status":404,
"message":"User with id 99 not found",
"timestamp":"2024-01-15T10:30:00"
}
@RestControllerAdvice
When Spring starts up and sees a class marked with @RestControllerAdvice it registers it as the global exception interceptor. From that point on whenever any exception is thrown anywhere in your entire app Spring automatically routes it to this class first. @RestControllerAdvice tells Spring — "I have a class that knows how to handle exceptions. Send all exceptions there before sending anything to the client."
When an exception is thrown in your app it bubbles up through Service → Controller. When it reaches the Controller Spring does not know what to do with it and just sends back a generic ugly 500 error to the client.
// exception/GlobalExceptionHandler.java
@RestControllerAdvice
publicclassGlobalExceptionHandler {
// all exception handling logic lives here
}
It is a combination of two annotations :
@ControllerAdvice — makes this class apply globally to all controllers in your application. Without this the class would only work for one specific controller.
@ResponseBody — makes every method in this class automatically convert its return value to JSON. Without this Spring would try to return a view instead of JSON.
You combine both into @RestControllerAdvice which is cleaner and the standard way in REST APIs.
NOTE : You only ever need one @RestControllerAdvice class in your entire project. It automatically intercepts exceptions from every single controller. Never create two — if two handlers handle the same exception Spring does not know which one to pick and behavior becomes unpredictable.
@ExceptionHandler
Now that Spring knows your GlobalExceptionHandler class handles exceptions, it needs to know which method inside that class handles which exception. That is what @ExceptionHandler does.
You put @ExceptionHandler on a method and tell it which exception class it is responsible for. When that specific exception is thrown Spring finds the method with the matching @ExceptionHandler and calls it automatically :
@RestControllerAdvice
publicclassGlobalExceptionHandler {
// Spring calls this ONLY when UserNotFoundException is thrown
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
// ex — the actual exception object that was thrown
// ex.getMessage() — the message you set when creating the exception
NOTE : The order of `@ExceptionHandler` methods matters. Spring picks the first matching handler it finds going top to bottom. Always put specific exceptions first and `Exception.class` last. If you put `Exception.class` first it catches every single exception and your specific handlers below it never get called.
ResponseEntity
By default when you return an object from a controller Spring always sends 200 OK as the status code. But not every response should be 200. Without ResponseEntity you have no way to control which status code gets sent back. Spring just always sends 200. It is a wrapper that holds 2 things :
ResponseEntity
├── Body → the actual data you want to return (User, ErrorResponse etc.)
└── Status → the HTTP status code you want to send (200, 201, 404 etc.)
Think of it like putting your response in an envelope. The envelope is ResponseEntity — it contains the letter (your body) and a label (the status code). Without ResponseEntity Spring just sends the letter with a default 200 label always. How to create a ResponseEntity :
// Full syntax
new ResponseEntity<>(body, HttpStatus.STATUS_CODE)
// Examples
new ResponseEntity<>(user, HttpStatus.OK) // 200 with user
new ResponseEntity<>(user, HttpStatus.CREATED) // 201 with user
new ResponseEntity<>(error, HttpStatus.NOT_FOUND) // 404 with error
new ResponseEntity<>(null, HttpStatus.NO_CONTENT) // 204 with no body
HttpStatus is an enum that contains every standard HTTP status code as a readable named constant. Instead of remembering numbers you use names. You use it with ResponseEntity to set the right status code :
HttpStatus.OK // 200 — request successful
HttpStatus.CREATED // 201 — resource created successfully
HttpStatus.NO_CONTENT // 204 — success but nothing to return
HttpStatus.BAD_REQUEST // 400 — client sent invalid data
HttpStatus.UNAUTHORIZED // 401 — client is not logged in
HttpStatus.FORBIDDEN // 403 — logged in but no permission
HttpStatus.NOT_FOUND // 404 — resource does not exist
HttpStatus.INTERNAL_SERVER_ERROR // 500 — unexpected server error
NOTE : ResponseEntity is used in 2 places — in your controllers to return the correct status on success, and in your GlobalExceptionHandler to return the correct status on error. Together they ensure every single response from your API always has the right HTTP status code.
// ❌ Without ResponseEntity
@PostMapping
public User createUser(@RequestBody User user) {
return userService.createUser(user);
// always returns 200 — wrong, should be 201
}
// ✅ With ResponseEntity
@PostMapping
public ResponseEntity<User>createUser(@RequestBody User user) {
Together they ensure every single response from your API has the correct HTTP status code. Without ResponseEntity in the controller your success responses are always wrong even if your error responses are correct.
Entity - An Entity is a class marked with @Entity that maps directly to a database table. It represents how your data is stored in the database. Every field in the Entity becomes a column in the table.
private Stringpassword; // stored in database — hashed
private Stringrole; // stored in database
privatebooleanactive; // stored in database
@CreationTimestamp
private LocalDateTimecreatedAt;
}
The Problem with Using Entity Everywhere
Imagine you use the User entity directly as your request and response object. Two problems immediately appear :
Problem 1 — Receiving data from client
When a client creates a user they should only send name, email, and password. But if you use the User entity directly the client could also send id, role, active, createdAt — fields they should never be allowed to set.
// Client sends this — they set their own role!
{
"name":"Deepesh",
"email":"deepesh@gmail.com",
"password":"secret123",
"role":"ADMIN" ← security risk
}
Problem 2 — Sending data to client
When you return a user to the client you should never send the password field. But if you return the User entity directly the password goes out to the client.
// Client receives this — password exposed!
{
"id":1,
"name":"Deepesh",
"email":"deepesh@gmail.com",
"password":"hashed_password_here" ← security risk
}
DTO (Data Transfer Object)
A DTO (Data Transfer Object) is a plain Java class with no @Entity annotation. It is not mapped to any database table. It only exists to carry data between the client and your app — nothing more.
In Spring Boot you will hear both terms — DTO (Data Transfer Object) and Model — used to describe the same thing. They are just different names for a plain Java class with no @Entity annotation that carries data between the client and your application.
You create separate DTOs for what comes in from the client and what goes out to the client :
// DTO for receiving data FROM client — only fields client is allowed to send
publicclassCreateUserRequest {
@NotBlank(message="Name cannot be empty")
private Stringname;
@Email(message="Must be a valid email")
private Stringemail;
@Size(min=8, message="Password must be at least 8 characters")
private Stringpassword;
// no id — client never sets id
// no role — client never sets their own role
// no active — client never sets this
// no createdAt — client never sets this
// getters and setters
}
// DTO for sending data TO client — only fields client is allowed to see
publicclassUserResponse {
privateintid;
private Stringname;
private Stringemail;
private Stringrole;
private LocalDateTimecreatedAt;
// no password — never expose password to client
// no active — internal field, client does not need this
// getters and setters
}
We can then use it like this in our service and controllers wherever we need to mention the data structure of incoming or outgoing data.
@Service
publicclassUserService {
@Autowired
private UserRepositoryuserRepository;
public UserResponse createUser(CreateUserRequest request) {
// Convert DTO to Entity
Useruser=newUser();
user.setName(request.getName());
user.setEmail(request.getEmail());
user.setPassword(request.getPassword()); // hash this in real app
user.setRole("USER"); // always set role in service, never from client
user.setActive(true);
// Save Entity to database
UsersavedUser= userRepository.save(user);
// Convert Entity to Response DTO
UserResponseresponse=newUserResponse();
response.setId(savedUser.getId());
response.setName(savedUser.getName());
response.setEmail(savedUser.getEmail());
response.setRole(savedUser.getRole());
response.setCreatedAt(savedUser.getCreatedAt());
// password is NOT included in response
return response;
}
}
Entity → maps to database table, used by Repository and JPA
DTO (Request) → what client sends in, has validation annotations
DTO (Response) → what client receives, only safe fields included
Client → DTO (Request) → Entity → Database
Database → Entity → DTO (Response) → Client
NOTE : In small projects and tutorials people often skip DTOs and use the Entity directly to keep things simple. This works but is bad practice because it exposes your database structure and creates security risks. In real production projects you always use DTOs. The extra code is worth the security and flexibility it provides.
Validation is the process of checking incoming data before it reaches your service or database and rejecting it immediately with a meaningful error if it does not meet your rules. Without validation your app happily accepts this garbage data and saves it to the database — corrupting your data and potentially breaking your app.
Spring Boot has a built in validation library. You add annotations to your DTO fields to define the rules and Spring automatically validates incoming data before your controller method even runs. If validation fails Spring throws an exception which your GlobalExceptionHandler catches and returns a clean error response.
Step 1 — Add Dependency
First add the validation library to your pom.xml :
Spring provide different validation annotations, these annotations go on your DTO fields to define the rules. Every annotation has a message property that defines what the client receives when that rule is violated.
You add validation annotations directly on your DTO fields to define the rules. Each annotation has a message property that defines the error message the client receives when that rule is violated :
import jakarta.validation.constraints.*;
publicclassCreateUserRequest {
@NotBlank(message="Name cannot be empty")
@Size(min=2, max=50, message="Name must be between 2 and 50 characters")
private Stringname;
@NotBlank(message="Email cannot be empty")
@Email(message="Must be a valid email address")
private Stringemail;
@Min(value=18, message="Age must be at least 18")
@Max(value=100, message="Age must be less than 100")
privateintage;
@NotBlank(message="Password cannot be empty")
@Size(min=8, message="Password must be at least 8 characters")
private Stringpassword;
// getters and setters
}
NOTE : Always use @NotBlank for String fields — it is the strictest and covers all 3 cases. Only use @NotNull for non-String types like Integer, Boolean, LocalDate etc.
NOTE : You can stack multiple annotations on one field. Spring runs all of them and collects all failures at once.
Step 3 — @Valid - Enable Validation in Controller
Add @Valid on the @RequestBody parameter in your controller. This tells Spring to validate the incoming object before passing it to your method. Without @Valid Spring ignores all your validation annotations completely :
The @Valid is added to every controller that needs to validate its DTO class object validation to check again the data sent by the user. Without it Spring ignores all your validation annotations and never validates anything regardless of what annotations you put on your DTO fields. POST and PUT requests send a body so they always need @Valid.
@RestController
@RequestMapping("/users")
publicclassUserController {
// ✅ Has @RequestBody — add @Valid
@PostMapping
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) { }
// ✅ Has @RequestBody — add @Valid
@PutMapping("/{id}")
public ResponseEntity<UserResponse> updateUser(@PathVariableintid, @Valid @RequestBody UpdateUserRequest request) { }
// ❌ No @RequestBody — no need for @Valid
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUserById(@PathVariableintid) { }
// ❌ No @RequestBody — no need for @Valid
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariableintid) { }
}
Step 4 — Handle Errors in GlobalExceptionHandler
When validation fails Spring automatically throws MethodArgumentNotValidException. You handle it in your GlobalExceptionHandler to return a clean error response.
You have 2 options — return only the first error or return all errors at once :
NOTE : Validation annotations go on your DTO — not your @Entity class. The Entity is for database mapping, the DTO is for incoming data validation. Never mix the two.
NOTE : @Valid must be added on the @RequestBody parameter in your controller. Without it Spring ignores all your validation annotations and never validates anything.
## How it all flows
POST /users with invalid data
↓
@Valid triggers validation on @RequestBody
↓
Validation fails — name is empty, email is invalid
↓
Spring throws MethodArgumentNotValidException automatically
4] If everything passes → calls your controller method normally
↓
If anything fails → throws MethodArgumentNotValidException automatically
your controller method is NEVER called
GlobalExceptionHandler catches it and returns 400
You never manually throw MethodArgumentNotValidException. You never write a single line of validation logic. Spring does all of it automatically just because you added @Valid on @RequestBody and validation annotations on your DTO fields.
Instead of fetching everything at once you fetch only what the client needs at that moment, Pagination returns data in small chunks called pages. Sorting lets the client decide the order of results. Without it data comes back in whatever order the database feels like — completely unpredictable and unusable.
Spring Data JPA has pagination and sorting completely built in. You do not write a single line of SQL. Just a few small changes to your Repository, Service, and Controller and it works automatically.
Spring Data JPA generates LIMIT and OFFSET SQL automatically behind the scenes. You never write these yourself. The formula Spring uses :
OFFSET = pageNumber × pageSize
Page 0 → SELECT * FROM products LIMIT 10 OFFSET 0 ← products 1 to 10
Page 1 → SELECT * FROM products LIMIT 10 OFFSET 10 ← products 11 to 20
Page 2 → SELECT * FROM products LIMIT 10 OFFSET 20 ← products 21 to 30
NOTE : Implementing pagination and sorting only requires 3 small changes — one in the Repository, one in the Service, and one in the Controller.
JpaRepository already includes PagingAndSortingRepository which gives you pagination methods automatically. You do not need to change anything in the repository layer.
In service layer Instead of returning List<Product> you return Page<Product>. You accept page number, page size, sort field, and sort direction as parameters and create a Pageable object from them. Spring uses this Pageable to generate the right LIMIT and OFFSET SQL automatically :
NOTE : When Spring returns a Page object it contains much more than just the data. The frontend uses totalPages and totalElements to build pagination UI like "Page 1 of 100" or "Showing 1-10 of 1000 results" :
{
"content": [ {...}, {...} ], ← the actual data
"pageNumber":0, ← current page
"pageSize":10, ← items per page
"totalElements":1000, ← total items in database
"totalPages":100, ← total number of pages
"first":true, ← is this the first page
"last":false ← is this the last page
}
Do All JPA Methods Accept Pageable?
No. Only read methods that return multiple results support Pageable. It makes no sense to paginate a save, delete, or single item fetch. When you extend JpaRepository you are not just getting one interface — you are getting a chain of interfaces stacked on top of each other. Each interface in the chain adds more functionality :
JpaRepository ← what you extend
↑ extends
PagingAndSortingRepository ← adds pagination and sorting support
↑ extends
CrudRepository ← adds basic CRUD methods
↑ extends
Repository ← base marker interface
// ✅ Makes sense with Pageable — returns multiple results
// ❌ Makes no sense with Pageable — single result or no result
save(entity) // saving one record
deleteById(id) // deleting one record
findById(id) // fetching one record
existsById(id) // checking existence
count() // counting records
For your own derived methods and @Query methods you can add Pageable as the last parameter and Spring automatically applies it to the generated query :
// Derived method — just add Pageable as last parameter
// Spring applies LIMIT and OFFSET to your custom query automatically
NOTE : Spring automatically detects the Pageable parameter and applies pagination to the query. You never manually add LIMIT or OFFSET — Spring handles it entirely behind the scenes.
Pagination with Derived Methods
Without pagination your derived method returns everything that matches :
// Without pagination — returns ALL products in that category
List<Product>findByCategory(String category);
// SQL : SELECT * FROM products WHERE category = ?
// if 50,000 products in "Electronics" — returns all 50,000
With pagination you just change the return type to Page<T> and add Pageable as the last parameter. Spring sees the Pageable parameter and automatically adds LIMIT and OFFSET to the generated SQL :
// With pagination — returns only the requested page
// SQL : SELECT * FROM products WHERE category = ? LIMIT ? OFFSET ?
// now returns only 10 products at a time
@Query Methods with Pagination
Same concept applies to @Query methods. You write your JPQL or raw SQL as normal and just add Pageable as the last parameter. Spring takes your query and wraps it with LIMIT and OFFSET automatically :
// Without pagination
@Query("SELECT p FROM Product p WHERE p.price < :price")
// SQL : SELECT * FROM products WHERE price < ? LIMIT ? OFFSET ?
NOTE : The Pageable parameter must always be the last parameter in your method. If you put it anywhere else Spring cannot detect it and pagination will not work.
NOTE : You never need to modify your JPQL or SQL query to add pagination. Spring automatically wraps your query with LIMIT and OFFSET based on the Pageable object you pass in. Your query stays clean and focused on filtering — Spring handles the pagination part.
Sorting
Sorting lets you control the order in which data is returned. Spring Data JPA supports sorting both with and without pagination. Sorting controls the order in which data is returned from the database. Spring Data JPA supports sorting across all 3 types of repository methods — built-in methods, derived methods, and @Query methods. Spring automatically adds ORDER BY to the SQL based on how you specify the sort.
Sorting with Built-in Methods
These are the findAll() methods that come from JpaRepository. You pass a Sort object directly :
// SQL : SELECT * FROM products ORDER BY price ASC LIMIT 10 OFFSET 0
}
}
Sorting with Derived Methods
You have 2 ways to add sorting to derived methods :
1] Sort in the method name — you define the sort directly in the method name using OrderBy. Spring reads the method name and generates ORDER BY in the SQL automatically. The sort is always fixed — the client cannot change it.
// SQL : SELECT * FROM products WHERE category = ? ORDER BY price DESC
// Sort by multiple fields in method name
List<Product> findAllByOrderByPriceAscNameDesc();
// SQL : SELECT * FROM products ORDER BY price ASC, name DESC
}
2] Sort via Pageable — you pass a Pageable object with sort information. The client controls the sort field and direction at runtime. More flexible than method name sorting.
When you build a REST API your frontend developers, mobile developers, or any other team that uses your API need to know :
What endpoints exist
What data each endpoint expects
What each endpoint returns
What HTTP method to use
What status codes to expect
Without Swagger you would have to write all of this manually in a Word document or Notion page and keep it updated every time your API changes. This is tedious, error prone, and always ends up outdated.
Swagger solves this by automatically generating interactive API documentation directly from your code. It reads your controllers, annotations, and models and generates a beautiful documentation page that is always up to date because it is generated from your actual code.
That is literally all you need. Just adding this dependency automatically generates the documentation. No extra configuration required. Go to http://localhost:8080/swagger-ui.html.
Customizing Swagger — Optional Annotations
By default Swagger generates basic documentation from your code. You can add annotations to make it more descriptive and useful :
Swagger Annotations — Simple Example
Imagine you have a simple UserController with 2 endpoints. Without annotations Swagger still generates documentation but it looks generic. With annotations it becomes descriptive and useful :
import io.swagger.v3.oas.annotations.*;
import io.swagger.v3.oas.annotations.responses.*;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.media.*;
// Groups both endpoints under "Users" in Swagger UI
@Tag(name="Users", description="Everything related to users")
@RestController
@RequestMapping("/users")
publicclassUserController {
@Autowired
private UserServiceuserService;
// Describes what this endpoint does
@Operation(
summary="Get user by id",
description="Fetches a single user from the database using their id"
)
// Describes possible responses
@ApiResponses({
@ApiResponse(responseCode="200", description="User found successfully"),
@ApiResponse(responseCode="404", description="User with this id does not exist")
})
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(
// Describes the path variable
@Parameter(description="Id of the user you want to fetch", example="1")
<packaging>jar</packaging><!-- This is default, can be omitted -->
Step 2: Build the JAR
bash
./mvnw clean package
This creates: target/myapp-0.0.1-SNAPSHOT.jar
Step 3: Run the JAR
bash
java-jar target/myapp-0.0.1-SNAPSHOT.jar
That's it! Your app is now running on port 8080.
Common Variations
Run with custom port
bash
java-jar myapp.jar --server.port=8081
Run with production profile
bash
java-jar myapp.jar --spring.profiles.active=prod
Why JAR is Preferred for Microservices
1. Self-Contained
bash
# One JAR contains everything
myapp.jar
├── Your application code
├── Spring Boot framework
├── Embedded Tomcat server
└── All dependencies
# Run anywhere with just Javajava-jar myapp.jar
Useful : 1] Click 2] " Click " NOTE : In the "Reducer" function always have a 'default' switch case,else you'll get Undefined state error. Redux.JS Redux is an open-source state management javascript library. As the application grows, it becomes difficult to keep it organized and maintain data flow. Redux solves this problem by managing application’s state with a single global object called Store. Redux itself is a standalone library that can be used with any UI layer or framework, including React, Angular, Vue, Ember, and vanilla JS. Although Redux and React are commonly used together, they are independent of each other. NOTE : The data in react always flows from parent to child components,which makes react "Unidirectional" . Unlike react, Angular makes use of bi-directional binding in which the data flow takes place in both directions. What problem does Redux solve ? So, state is everywhere in ...
Useful : 1] Click 2] Click 3] React Roadmap React is an open source, JavaScript library for developing user interface (UI) in web application. React is developed and released by Facebook in 2013 . React has a component based architecture i.e everything is a component ,this let you break-down your application into small parts which can then be composed to make complex interfaces. In the past, when browsers were much less capable than today, and JavaScript performance was poor, every page was coming from a server. Every time you clicked something, a new request was made to the server and the browser subsequently loaded the new page. Today, popularized by modern frontend JavaScript frameworks like React, an app is usually built as a single page application: you only load the application code (HTML, CSS , JavaScript ) once, and when you interact with the application, what generally happens is that JavaScript intercepts the browser events and instead of making ...
Module Bundlers ( Useful :1] Click 2] Click ) Web browsers can only understand and execute JavaScript, HTML and CSS . However, developers often use other technologies and tools like React, Sass, TypeScript, and Tailwind to improve the development process, write more maintainable code, and add additional functionality to their applications. We need a way to combine all this JS & CSS code into a single optimized javascript file, this is achieved through module bundling. A module bundler is a tool that takes all the JavaScript files in a project and combines them into a single JS file (or a few files) that can be loaded by a browser. It usually starts with an entry point file, and from there it will start looking for "import" statements and then bundles up all of code needed for that entry file. The entry point is typically defined in the config file of the bundler. The entry point is the file where the bundler starts its traversal of the application's dependencies...
Comments
Post a Comment