What is Webpack ? (Current version v4.x)
- Webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it recursively builds a dependency graph that includes every module your application needs, then packages all of those modules into one or more bundles.
The Core Concepts you must to know:
- Entry
- Output
- Loaders
- Plugins
- Mode
Entry
An entry point indicates which module webpack should use to begin building out its internal dependency graph. After entering the entry point, webpack will figure out which other modules and libraries that entry point depends on (directly and indirectly).
Every dependency is then processed and outputted into files called bundles, which we'll discuss more in the next section.
You can specify an entry point (or multiple entry points) by configuring the entry property in the webpack configuration. It defaults to ./src.
Here's the simplest example of an entry configuration:
//webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js'
};
Ouput
The output property tells webpack where to emit the bundles it creates and how to name these files, it defaults to ./dist. You can configure this part of the process by specifying an output field in your configuration:
// webpack.config.js
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};
Loaders
Loaders enable webpack to process more than just JavaScript files (webpack itself only understands JavaScript). They give you the ability to leverage webpack's bundling capabilities for all kinds of files by converting them to valid modules that webpack can process.
Essentially, webpack loaders transform all types of files into modules that can be included in your application's dependency graph (and eventually a bundle).
At a high level, loaders have two purposes in your webpack configuration:
The test property identifies which file or files should be transformed.
The use property indicates which loader should be used to do the transforming.
// webpack.config.js
const path = require('path');
const config = {
output: {
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};
module.exports = config;
Plugins
While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks. Plugins range from bundle optimization and minification all the way to defining environment-like variables. The plugin interface is extremely powerful and can be used to tackle a wide variety of tasks.
In order to use a plugin, you need to require() it and add it to the plugins array. Most plugins are customizable through options. Since you can use a plugin multiple times in a config for different purposes, you need to create an instance of it by calling it with the new operator.
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
const config = {
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
How to use Webpack
Create a new directory project & cd to in it:
mkdir webpack-project && cd $_
Initialize a package.json by running:
npm init
Install Webpack
npm i webpack webpack-cli --save-dev
Now open up package.json and add a build script:
"scripts": {
"build": "webpack"
}
Create an Index file as index.js with content in src folder
console.log('Webpack auto come here by default')
mkdir src && src/index.js
Finally, You can Run it to see
npm run build
Webpack with common task
Transpiling Javascript ES6 with Babel
Modern Javascript is mostly written in ES6.
But not every browser know how to deal with ES6. We need some kind of transformation.
This transformation step is called transpiling. Transpiling is the act of taking ES6 and making it understandable by older browsers.
To start using the loader we need to install a bunch of dependencies. In particular:
- babel-core
- babel-loader
- babel-preset-env for compiling Javascript ES6 code down to ES5
npm i babel-core babel-loader babel-preset-env --save-dev
Next up configure Babel by creating a new file named .babelrc inside the project folder:
// .babelrc
{
"presets": [
"env"
]
}
Create a new file named webpack.config.jsand configure the loader:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
Come back to src/index.js file and write some code here with ES6 syntax
let a = [2,4,6,8,10];
a.map((num) => num+1);
OK_ Now we let go to see What Webpack can do
npm run build
And Now, You can take a look at ./dist/main.js to see the transpiled code.
Setting up webpack with React
To start we need to install React library
npm i react react-dom --save-dev
Next up add babel-preset-react:
npm i babel-preset-react --save-dev
Configure update the preset in .babelrc:
{
"presets": ["env", "react"]
}
We will create a App.js file in src folder
touch src/App.js
Now we will create a React Component like in the App.js
// App.js
import React from "react";
import ReactDOM from "react-dom";
const App = () => {
return (
<div>
<p>React here!</p>
</div>
);
};
export default App;
ReactDOM.render(<App />, document.getElementById("app"));
Finally in the Index file we will import App component
import App from "./App";
NOW MAKE WEBPACK WORK
npm run build
OK FINE - IF THERE IS NO PROBLEM - LET GO TO SEE RESULT IN THE DIST MAIN.JS.
The HTML webpack plugin
Webpack needs two additional components for processing HTML: html-webpack-plugin and html-loader.
npm i html-webpack-plugin html-loader --save-dev
Update Webpack.config.js like below
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
})
]
};
Now you should create an index.html file in src folder
touch src/index.html
Index.html file with this content
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Webpack Demo</title>
</head>
<body>
<div id="app">
</div>
</body>
</html>
Finally your run
npm run build
Come to Dist folder to see result
Extracting CSS to a file
- Note with the version 4.x We will use mini-css-extract-plugin replace for extract-text-webpack-plugin
Ok, let we go to install the plugin and css-loader with:
npm i mini-css-extract-plugin css-loader --save-dev
We'll create a CSS file in src folder
touch src/main.css
// main.css
body {
background: #ccc;
}
Update Webpack.config.js File like below
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
]
};
Import css file to Index.js
// index.js
import style from "./main.css";
Finally you run
npm run build
Go to dist and open index.html file by chrome you see result with css style.
The webpack dev server
Running npm run devwhenever you make changes to your code? Far from ideal.
It takes just a minute to configure a development server with webpack.
Once configured webpack dev server will launch your application inside a browser.
It will automagically refresh the browser’s window as well, every time you change a file.
To set up webpack dev server install the package with:
npm i webpack-dev-server --save-dev
Update package.json Script
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build": "webpack --mode production"
}
And Now, you can start all by one thing
npm start
Production and development mode
Webpack having 2 configuration files is a common pattern in webpack.
- Development
- Production
"scripts": {
"start": "webpack-dev-server --mode development --open",
"build": "webpack --mode production"
}
Now, you delete dist folder (if it created) and run
npm start
You can see nothing happen in source code
Now, you run with
npm run build
You will see dist build, and js bundle file. THAT'S PRODUCTION MODE.
THANKS FOR READING
Resource relate
- Webpack (https://webpack.js.org.org)
- Valentinog Blog (https://www.valentinog.com/)