
A quick tutorial on how to configure Webpack with multiple outputs.
Building Web Applications with Node is easy! There is a great number of frameworks, and tools that help programmer to bootstrap an environment and start working in just a matter of seconds. Some of them generate a bunch of boilerplate, like Create React App, while others help to eliminate it, like Gatsby. In one case, you might have a setup that you might not necessary want, in another, you are bound to certain conventions. Moreover, developers often want to have their React, Angula, Vue (insert your favorite UI library) front ends served from Express, Koa, Hapi (insert your favorite server side library). One approach is to use client side routing library, which adds more complexity to your application when implementing certain features, like authentication.
In this tutorial, I will show you how to create a basic setup for server side routing. I am going to use Express, and Preact, but the overall workflow is similar no matter the framework. The complete code of this tutorial can be foundhere, on GitHub. That said, I hope you will follow along instead of just jumping straight to the solution!
Alrighty, let’s begin! The easiest way to start with Express application is express-generator. We can use bare bone express app, but I want to show how you can combine Express template engine with front end UI library. For this tutorial I will use Pug aka Jade. So, let’s boostrap a new Express application:
npx express-generator--pug--git express-webpack-template
Once generator did it work, we cancd
(ordir
if you are on command prompt) into application folder. Next step is to install all the dependencies:
cdexpress-webpack-templatenpm i
If you look at the project structure, it looks the following way:
├── bin│ └── www├── public│ ├── images│ ├── javascripts│ └── stylesheets│ └── style.css├── routes│ ├── index.js│ └── users.js├── views│ ├── error.pug│ ├── index.pug│ └── layout.pug├── app.js├── package.json└── package-lock.json
Let’s move on to installing all the development dependencies:
npm i-D webpack webpack-cli nodemon
For those who are not familiar, Webpack is a tool for bundling JavaScript, and Nodemon is an utility to restart Node process if changes in source code where detected.
To further simplify the workflow, I recommend to add the following scripts to yourpackage.json
file:
..."scripts":{"start":"node ./bin/www","start:dev":"nodemon ./bin/www","build":"webpack --config webpack.config.js","build:dev":"webpack --config webpack.config.js -w"},...
Now let’s start our application for the first time!
npm run start:dev
Now, open your browser onlocalhost:3000
, and woah!
Let’s add some interactivity! Since the main purpose of this tutorial is to show Webpack configuration for multiple bundles, we need to create more pages! Express-generator created two separate routers:index.js
andusers.js
. Let’s changeusers.js
router to look the following way:
// routes/users.jsvarexpress=require('express');varrouter=express.Router();/* GET users listing. */router.get('/',function(req,res,next){res.render('users',{title:'Users'});});module.exports=router;
Now, express know that we need to render users.pug template on/users
route. Let’s create this template in views folder. It might look like this:
// views/users.pugextends layoutblock content h1= title p Welcome to #{title} a(href='/') Go to home page
Also, add a tag withhref
property toindex.pug
, to go back and forth between pages.
Let’s add some front end libraries! As stated previously, I am going to install Preact! I will pair it with HTM. This way, we don’t have to waste time installing Babel, and tutorial will only be focused on bundling for server side routing. That said, the principle itself applies to more complex setups either.
npm i preact htm
If you have never used HTM, it is template language similar to JSX, used by React, but it is plain JS.
Anyway, let’s create create 3 JavaScript components files inpublic/javascripts
:
// public/javascripts/index.jsimport{h,Component,render}from'preact';import{html}from'htm/preact';import{Navbar}from'./shared';classIndexPageextendsComponent{render(){returnhtml` <${Navbar}/> <div> <div> <h3>Welcome to Home Page!</h3> <p>This application uses Express and Webpack!</p> <div> <a href="/users">See Users</a> </div> </div> </div> `;}}render(html`<${IndexPage}/>`,document.getElementById('app'));
// public/javascripts/users.jsimport{h,Component,render}from'preact';import{html}from'htm/preact';import{Navbar}from'./shared';classUsersPageextendsComponent{addUser(){const{users=[]}=this.state;this.setState({users:users.concat(`User${users.length}`)});}render({page},{users=[]}){returnhtml` <${Navbar}/> <div> <div> <h3>Welcome to Users page!</h3> <p>Click a button to add more users!</p> <ul>${users.map(user=>html` <li>${user}</li> `)} </ul> <div> <button onClick=${()=>this.addUser()}> Add User </button> <a href="/">Go back Home</a> </div> </div> </div> `;}}render(html`<${UsersPage} />`,document.getElementById('app'));
// public/javascripts/shared.jsimport{html}from'htm/preact';constNavbar=()=>html`<nav role="navigation" aria-label="main navigation"> <div> <a href="https://bulma.io"> Webpack Express Template </a> </div></nav>`;export{Navbar}
Now, let’s get to the main part! We need to bundle this Javascript, and only ship it on respective route! If you noticed earlier we provided awebpack.config.js
file to the Webpack script inpackage.json
. Let’s go ahead and create this file. Bare minimum for bundling multipage project is going to look like that:
webpack.config.jsconstpath=require('path');module.exports={entry:{index:'./public/javascripts/index.js',users:'./public/javascripts/users.js',},output:{path:path.resolve(__dirname,'public/javascripts'),filename:'[name].bundle.js'}};
Notice, how we use[name].bundle.js
as output filename. It tells react to create two files:index.bundle.js
andusers.bundle.js
. The only thing we have left now, is to adddiv
element with propertid="app"
in our pug templates, so that Preact can bind to it.
I also added some othermeta
tags, as well as Bulma import in layout template, so it would look a bit prettier. That’s what we have at this point:
// views/layout.pugextends layoutblock content div(id="app") script(src='javascripts/users.bundle.js')
// views/index.pugextends layoutblock content div(id="app") script(src='javascripts/index.bundle.js')
// views/users.pugextends layoutblock content div(id="app") script(src='javascripts/users.bundle.js')
Finally, let’s run Webpack, and bundle JavaScript!
npm run build
If you killed your express server, it is time to restart it! Once again, open up your browser onlocalhost:3000
. Your application should be looking similar tothis one:
One last thing, when developing, it is useful to use -w flag, which tells Webpack to automatically bundle scripts on any change.
That’s it! You configured your Webpack to build assets into multiple files! If you got lost at any point, again, all source code is available onmy GitHub.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse