Webpack 4 Plugin Demos
Entry file is a file which Webpack reads to build bundle, default bundle file in zero config is main.js
.
Default entry file for webpack 4 is index.js
, so created basic file with just alert
// index.js
document.write('<h1>Hello World, Basic Program with Zero config, without webpack.config.js</h1>');
Creating index.html
just to load bundle file.
index.html
<html>
<head>
<title>Demo01 Webpack Zero Config</title>
</head>
<body>
<script src="./dist/main.js"></script>
</body>
</html>
Default entry
file index.js
// index.js
document.write('<h1>Hello World, Basic Program with simple webpack.config.js</h1>');
<html>
<head>
<title>Demo02 Webpack simple Config</title>
</head>
<body>
<script src="./dist/main.js"></script>
</body>
</html>
Same demo01 example with below webpack.config.js
produce the same build
var path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
}
};
Multiple entry files are allowed. It is useful for a multi-page app which has different entry file for each page.
// main1.js first entry point
document.write('<h1>In main1 entry point</h1>');
// main2.js second entry point
document.write('<h2>In main2 entry point</h2>');
index.html
<html>
<head>
<title>Demo03 Multiple entry point for multi page application</title>
</head>
<body>
<script src="dist/bundle1.js"></script>
<!-- name specified for entry in webpack.config.js -->
<script src="dist/bundle2.js"></script>
<!-- name specified for entry in webpack.config.js -->
</body>
</html>
webpack.config.js
module.exports = {
entry: {
bundle1: './src/main1.js',
bundle2: './src/main2.js'
},
output: {
filename: '[name].js'
}
};
Install React and React Dom using command npm i react react-dom --save-dev
React components are mostly written in Javascript ES6.
Since the browser can’t understand React components as they come there is the need for some kind of transformation.
Webpack doesn’t know how to make the transformation but it has this concept of loaders: think of them as of transformers.
A Webpack loader takes something as the input and produces something else as the output.
babel-loader
is the Webpack loader responsible for taking in the ES6 code and making it understandable by the browser of choice.
Obsviusly babel-loadermakes use of Babel. And Babel must be configured to use a bunch of presets
:
- babel preset env for compiling Javascript ES6 code down to ES5 (please note that babel-preset-es2015 is now deprecated)
- babel preset react for compiling JSX and other stuff down to Javascript
Let’s pull in the dependencies with:
npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev
Loaders are preprocessors which transform a resource file of your app (more info) before Webpack's building process.
For example, Babel-loader can transform JSX/ES6 file into normal JS files,after which Webpack will begin to build these JS files. Webpack's official doc has a complete list of loaders.
main.jsx
is a JSX file.
// main.jsx
const React = require('react');
const ReactDOM = require('react-dom');
ReactDOM.render(
<h1>Hello, world!, Demo04 webpack using babel for react</h1>,
document.querySelector('#wrapper')
);
index.html
<html>
<head>
<title>Demo04 Babel loader for react transpilation</title>
</head>
<body>
<div id="wrapper"></div>
<script src="dist/bundle.js"></script>
</body>
</html>
webpack.config.js
module.exports = {
entry: './src/main.jsx',
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
}
]
}
};
Webpack allows you to include CSS in JS file, then preprocessed CSS file with CSS-loader.
Install loaders using command npm install css-loader style-loader --save-dev
The css-loader
interprets @import
and url()
like import/require()
and will resolve them.
index.js
require('./src/app.css'); // Just importing it so that it will add be used by dependency graph
app.css
body {
background-color: yellow;
}
index.html
<html>
<head>
<script type="text/javascript" src="./dist/bundle.js"></script>
</head>
<body>
<h1>Hello World, Background color set using CSS</h1>
</body>
</html>
webpack.config.js
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};
Attention, you have to use two loaders to transform CSS file. First is CSS-loader to read CSS file, and another one is Style-loader to insert <style>
tag into HTML page.
Actually, Webpack inserts an internal style sheet into index.html
.
<head>
<script type="text/javascript" src="bundle.js"></script>
<style type="text/css">
body {
background-color: yellow;
}
</style>
</head>
Install npm i css-loader mini-css-extract-plugin html-webpack-plugin --save-dev
main.css
body {
background-color: gray;
}
index.js
import style from './main.css'; // Just importing file
document.write(
'<h1>Hello World, Index file generated using HtmlWebPackPlugin and CSS is extracted in to separate file using MiniCssExtractPlugin </h1>'
);
webpack.config.js
const HtmlWebPackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new HtmlWebPackPlugin(), // Show with template
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
]
};
<html>
<head>
<title>Demo07 Webpack example CSS Extract and HTML Plugin</title>
</head>
<body>
<h1>I am in template file</h1>
</body>
</html>
// Update below code to use template file
new HtmlWebPackPlugin({
template: "./src/template.html",
filename: "./index.html"
}),
**NOTE: **
"sideEffects": false //Add this in package.json
To prevent tree shaking for css import add below in package.json
"sideEffects": [
"*.css"
]
Install url-loader
using command npm i url-loader html-webpack-plugin --save-dev
Webpack could also include images in JS files.
index.js
var img1 = document.createElement('img');
img1.src = require('./small.png');
document.body.appendChild(img1);
var img2 = document.createElement('img');
img2.src = require('./big.png');
document.body.appendChild(img2);
webpack.config.js
const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(png|jpg)$/,
use: [
{
loader: 'url-loader'
}
]
}
]
},
plugins: [new HtmlWebPackPlugin()]
};
NOTE Using HtmlWebPackPlugin
for generating index.html i.e loading the build bundle.
url-loader transforms image files into <img>
tag (Data URL).
After launching the server, small.png
and big.png
have the following URLs.
<img src="data:image/png;base64,iVBO.." /> <img src="data:image/png;base64,iaas.." />
Add Option for image size in url-loader
options
If the image size is smaller than 8192 bytes then , it will be transformed into Data URL; otherwise, it will be transformed into normal URL.
Now change the config for loader to use below:
{
loader: 'url-loader',
options: {
limit: 8192 // Note here added the limit of 8192 bytes so if image is greater than limit then do not use `url-loader`
}
}
So to load the image size > limit (8192 bytes) use
file-loaderi.e install dependency using
npm -i D file-loader`
webpack.config.js
const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(png|jpg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
},
plugins: [new HtmlWebPackPlugin()]
};
math.js
export function square(x) {
console.log('Returning square');
return x * x;
}
export function cube(x) {
console.log('Returning cube');
return x * x * x;
}
index.js
import { cube } from './math.js'; //Note we just
function component() {
var element = document.createElement('pre');
element.innerHTML = [
'Hello webpack!',
'5 cubed is equal to ' + cube(5)
].join('\n\n');
return element;
}
document.body.appendChild(component());
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
output: {
filename: 'bundle.js'
},
optimization: {
usedExports: true // This will show unused exports in bundle
},
plugins: [new HtmlWebPackPlugin()]
};