Webpack - Module Bundler
Nowadays, as a Frontend Developer, we use a lot of tools and new libraries to work on our projects and, sometimes, the browsers wont support some of the files that we are using. To resolve that problem module bundlers were created.
What is a Module Bundler?
A module bundler is a tool that will convert any number of files that are not supporte by the browser tofiles that the browser will support. For example the bundler will convert .sass files into .css. Even when you are working with some libraries, for example, lodash, it will converted to a code that the browser will understand.
How it works?
For example, we have the following project:
As you can see we have only two files, index.html and index.js. In the index.html we have a very basic structure and a call for the script file.
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
? ? <meta charset="UTF-8">
? ? <meta http-equiv="X-UA-Compatible" content="IE=edge">
? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">
? ? <title>Document</title>
</head>
<body>
? ? <script src="../src/index.js"></script>
</body>
</html>>
And in our JS file we will have only a console.log.
Index.js
console.log("Hello world")
When you run the HTML file on the browser, while inspecting the console, you will see that we received the "Hello world" string.
Until now we do not have any problems running our project. No image that you want to use lodash for any reason. In our case we are going to use the functionallity camelCase from the lodash. Before using it we need to create our package.json file, so let's get initialize it.
npm init -y
The code above will create a package.json file with a default configuration and by adding the "-y" it will answer yes to any questions that the configuration asks.
Once we have our package.json we can now install the lodash.
npm install lodash
Now we can go to our index.js file and import the lodash and use the camelCase functionallity.
import { camelCase } from "lodash"
console.log(camelCase("Hello world"));;
If we try to run the index.html file on the browser, you will notice that in the browser's console will appear an error. That error appears because the browser does not no how to work with imports.
That is way we need the bundlers, like webpack, that we are going to use from now on.
Webpack installation
npm install --save-dev webpack webpack-cli
After installing the webpack we need to do a little modification on our package.json file. on the scripts we are going to add a script to run the webpack.
...
"scripts": {
"build": "webpack",
}
When we run this script "npm run build" it will create a dist folder with the index.js file converted to a js file that the browser will understand.
If you open the main.js file, you will see that the code is "messy". That's the way webpack will convert our index.js file with the lodash.
That is the default webpack, but we can customize our webpack to do more then just converting JS files, we can configure our webpack to convert other files, for example Sass.
Customizing webpack
To do any type of configuration it is necessary to create a webpack file. That file will contain many attributes that we can use, so we are going to talk about some of them.
But first let's create our file.
领英推荐
webpack.config.js
module.exports = {
... add entries here
}
Now that we have our file created let's add attributes and talk about them.
Entry attribute
The entry attribute is where we are going to difine the point of entry to our app. This attribute can be a single string or a object with multiple entries. Here we are only use one entry.
module.exports = {
entry: './src/index.js'
}
Output attribute
This attribute will have the pah and name of the file where we want our compiled code to go. This attribute it is an object with 2 properties, filename and path. Since we want the configuration to be a little bit more dynamic we are going to use the path module to work around our path to the ./dist folder where the new compiled file is.
const path = require('path)
module.exports = {
entry: './src/index.js',
output: {
filename: 'compiled.js',
path: path.resolve(__dirname, 'dist')
}
}
Loader attribute
This attribute it will be used to process any file that is not Javascript, like for example, sass, markdown, etc. However for this attribute we need to install the loaders. We are going use the following loaders:
npm i --save-dev css-loader style-loader sass-loader
Now let's configure our file. To use the loaders we are going to use the module attribute with the rules property.
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'compiled.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
]
}
]
}
}
In the code the 'test' property will search for every file that contains .scss and then will compile it to a regular css file.
Plugins attribute
With the puglin attribute we can work with the bundler lifecycle. In our case we are going to use it to check wich file is using the most space in our project.
So let's configure it.
We are going to need to use the webpack bundler analyzer, for that we need to install it.
npm install --save-dev webpack-bundle-analyzer
After the installation we can continue configuring our webpack file.
const path = require('path')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
entry: './src/index.js',
output: {
filename: 'compiled.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
]
}
]
},
plugin: [
new BundleAnalyzerPlugin()
}
So if we run our project with the webpack build, the plugin will create an interactive treemap where we can check which file, or files are using more space in our app.
I beilive that you are tire of running our project over and over again, right? Do not worry, webpack has an attribute to listen our changes. Let's talk about it.
Dev-server attribute
This attribute will help us watch for any changes on our files.
To use this attribute we need to use the module webpac dev server. So it is time to install it.
npm i --save-dev webpack-dev-server
The dev-server will have to main attributes, contentBase, where we define the folder where the main content of our project is, and the second attribute is port, where we define the port that the webpack will use.
So the configuration will be, as follows:
const path = require('path')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
entry: './src/index.js',
output: {
filename: 'compiled.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
]
}
]
},
plugins: [
new BundleAnalyzerPlugin()
],
devServer: {
contentBase: path._join(__dirname, 'public'),
port: 9000
}
}
After this changes we need to do a final change, but in our package.json file. we are going to add a new line on scripts:
"dev": "webpack serve"
Now we can start the webpack and it will watch for any changes in our files.
In conclusion...