In this tutorial, I am going to show you how you can configure a javascript project using Webpack. For reference you can checkout this github repository for the code https://github.com/sujaykundu777/ts-webpack-boilerplateGithub Commit Ref Follow this change commit.
Create a new project
$ mkdir webpack-boilerplate
$ npm init -y
Now our package.json looks like :
{
"name": "ts-webpack-boilerplate",
"version": "1.0.0",
"description": "A Boilerplate for building webapps using TS",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Create Directories
$ mkdir src public
Create src/index.js
$ cd src
$ touch index.js
Paste the following code :
// our main file
console.log("hello world");
Create public/index.html
We will try to use Semantic HTML and Accessibility Aria Attributes wherever possible (best practices).
<!DOCTYPE html>
<html lang="en-US">
<head>
<title> Webpack Boilerplate </title>
<meta name="charset" content="UTF-8" />
<meta name="description" content="Webpack Boilerplate App" />
<meta name="keywords" content="javascript, typescript, webpack, boilerplate, webpack-boilerplate" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<header>
<div id="logo">
<h1> WEBPACK BOILERPLATE</h1>
</div>
</header>
<main>
<h1> This is a setup built on Webpack</h1>
</main>
<footer>
<p>© 2023</p>
</footer>
</body>
</html>
Create a .gitignore file ( to tell ignore not to commit this extension files)
.cache/
coverage/
dist/*
!dist/index.html
node_modules/
*.log
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
Folder structure :
Now our Project directory structure will look something like this :
webpack-boilerplate/
├── dist/
│ ├── index.html
├── src/
│ ├── index.js
│ └── ...
├── README.md
├── package.json
├── package-lock.json
├── .gitignore
└── ...
01 – Setup Webpack
We will use webpack for bundling our assets
npm install --save-dev webpack webpack-cli
Create a file -> webpack.config.js :
const webpack = require("webpack");
const path = require("path");
const config = {
mode: "development",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js",
},
};
module.exports = config;
Add watch script, In our package.json add the following command :
"scripts": {
"watch": "webpack --watch"
},
Now run watch command to make our dist/bundle.js :
npm run watch
You can see, webpack generated a bundle.js based on our entry : index.js file inside dist directory.
Your package.json will look like this :
```json
{
"name": "ts-webpack-boilerplate",
"version": "1.0.0",
"description": "A Boilerplate for building webapps using TS",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4"
}
}
```
Github Commit Ref Follow this change commit.
Let’s create a Basic App :
We will create the code with commonjs, but will optimise it later to use ESM.
We will create few pages Home, About, Contact Page
Modify index.html file like this :
<!DOCTYPE html>
<html lang="en-US">
<head>
<title> TS Webpack Boilerplate </title>
<meta name="charset" content="UTF-8" />
<meta name="description" content="TS Webpack Boilerplate App" />
<meta name="keywords" content="javascript, typescript, webpack, ts-boilerplate, webpack-boilerplate" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<header>
<div id="logo-container">
<h1> TS WEBPACK BOILERPLATE</h1>
</div>
<div id="nav-container">
<nav aria-label="Navigation">
<ul role="menu" aria-label="menu">
<li role="menuitem" aria-label="Home">
<a href="/"> Home </a>
</li>
<li role="menuitem" aria-label="About">
<a href="/about"> About </a>
</li>
<li role="menuitem" aria-label="Contact">
<a href="/contact"> Contact </a>
</li>
</ul>
</nav>
</div>
</header>
<main>
<h1> This is a setup built on Webpack, Typescript, SAAS</h1>
<div id="app"></div>
</main>
<footer>
<p>© 2023</p>
</footer>
</body>
</html>
Router
We need a router to show different views on link refs like ‘/‘, ‘/about’, ‘/contact’
Create a components/Router.js
class Router {
constructor(container) {
this.routes = {};
this.container = container;
this.currentRoute = null;
// Listen for changes in the URL
window.addEventListener("popstate", () => {
this.handleRouteChange(window.location.pathname);
});
}
// Add a route and its corresponding handler
addRoute(path, handler) {
this.routes[path] = handler;
}
// Handle a route change
handleRouteChange(path) {
if (this.routes[path]) {
// Call the handler for the current route
this.routes[path]();
this.currentRoute = path;
} else {
// Handle 404 - Route not found
console.log("Route not found");
}
}
// Initialize the router
init() {
// Handle the initial route
this.handleRouteChange(window.location.pathname);
}
}
module.exports = Router;
And in our index.js file:
// entry index.js
console.log("hello world");
// import Router
const Router = require("./components/Router");
// Get the container element where you want to render views
const appContainer = document.getElementById("app");
const router = new Router(appContainer);
router.addRoute("/", () => {
appContainer.innerHTML = "<h1>Welcome to the Home Page</h1>";
});
router.addRoute("/about", () => {
appContainer.innerHTML = "<h1>About Us</h1><p>This is the about page.</p>";
});
router.addRoute("/contact", () => {
appContainer.innerHTML = "<h1> Contact Us</h1><p> This is the contact page. </p>"
})
router.init(); // intialize our routes
Now serve the app :
npm run serve
Now you can see a menu with three links, Home, About and Contact. When you go the link it will show the particular view.
Adding Styles
So let’s add some global styling for our app, add a public/styles/global.css file:
body {
font-family: sans-serif;
}
#main-heading {
font-size: 40px;
color: red;
}
And add a heading in our public/index.html
<!DOCTYPE html>
<html lang="en-US">
<head>
<title> TS Webpack Boilerplate </title>
<meta name="charset" content="UTF-8" />
<meta name="description" content="TS Webpack Boilerplate App" />
<meta name="keywords" content="javascript, typescript, webpack, ts-boilerplate, webpack-boilerplate" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- our global styles -->
<link rel="stylesheet" type="text/css" href="./styles/global.css" />
</head>
<body>
<header>
<div id="logo-container">
<h1> TS WEBPACK BOILERPLATE</h1>
</div>
<div id="nav-container">
<nav aria-label="Navigation">
<ul role="menu" aria-label="menu">
<li role="menuitem" aria-label="Home">
<a href="/"> Home </a>
</li>
<li role="menuitem" aria-label="About">
<a href="/about"> About </a>
</li>
<li role="menuitem" aria-label="Contact">
<a href="/contact"> Contact </a>
</li>
</ul>
</nav>
</div>
</header>
<main>
<!-- add a id main-heading in our heading -->
<h1 id="main-heading"> This is a setup built on Webpack, Typescript, SAAS</h1>
<div id="app"></div>
</main>
<footer>
<p>© 2023</p>
</footer>
</body>
</html>
Serve the web app:
npm run serve
You should now be able to see the font changed and a red heading
Github Commit Ref Github commit reference for Setup routing and styling