Webpack & Babel for a Better JS.
===
## What is Webpack?
- It's an open-source module bundler, primarily for JavaScript!
- **Module Bundling:** It's the process of stitching a group of modules together, into a single file.
#### Hmmm, What? exactly?
- Webpack Allows us to use javascript modules within our browser by taking multiple files and assets and combining them into one big file.
-- One big file can kill initial load time for an app, doesn't it?
---
## Why Webpack?
It all begun with SPAs, On a single page application our app is windowed within one url and we never need to refresh. This is considered a nicer experience for the user as it feels slicker not having to refresh. In SPAs if we want to navigate from a page to another, unlike traditional server side rendered pages when the client's browser makes this request, the page will not refresh. Instead, the app will dynamically update itself in order to show the requested page content.
**Also:**
- Loads browser un-supported file types into valid ones.
- Code Mification, Linting and Optimization.
#### How is this related?
Basically, SPAs depend on one HTML template page where all the functionality that generates the dynamic content of the page exist, that's why we need a module bundler such like Webpack.
Functionality goes into the HTML page by importing the JS script files that we write, such like the components and there methods, that means, we get a script element in the HTML page that loads this functionality, but...
Considering that real Apps usually have dozens or maybe hundereds of JS files, it won't make sense just have a `script` element for all of these files, and here comes the hero Webpack generating a one bundled file including every JS file, image or anyother kind of assets we have in the project.

---
## Configuring Webpack.
### Installing Webpack:
`npm install webpack webpack-cli --save-dev`
- **webpack:** is the bundler itself.
- **webpack-cli:** allows the use of webpack from the command line.
### Adding our build script:
The script that we run to bundle everything!
```javascript
"scripts": {
"build": "webpack --config webpack.config.js"
},
```
### Resolution Process:
- **Entry:** This holds the start point of your application from where webpack can identify its dependencies.
- **Output:** This specifies where you would like the processed bundle to be saved.
- **Loaders:** These are a way of converting one thing as an input and generating something else as an output. They can be used to extend webpack’s capabilities to handle more than just JavaScript files, and therefore convert those into valid modules as well.
- **Plugins:** These are used to extend webpack’s capabilities into other tasks beyond bundling — such as code minification, linting, optimization and bundle splitting.

### Kicking off with Configuration:
```
const path = require("path");
module.exports = {
mode: 'development',
entry: "./src/js/index.js",
output: {
path: path.resolve(__dirname, "public"),
filename: "bundle.js"
}
};
```
---
## Transpiling:
Here comes `babel`. We know have known that _loaders_ are responsible for converting one thing `.scss` to another `.css`, what about the syntax itself? that's why we are integrating both _babel_ and _webpack_ together.
Babel would be responsible for the transpilation of a syntax, to another.. such as: JavaScript's ES6 to ES5.
#### Why?
Bowser friendship: browsers are just programs that read programming languages such as JavaScript, also markup languages such like HTML/CSS.
What if we had a new language? or, a new syntax to a language, wouldn't take time until the mainainers of a browser -such as Google to Chorme- be able to implement the capability of reading this language/syntax in their browser? it will.
That's why _babel_, babel has the plugins that come with every language/syntax published by the authors, which is used to transpile one thing to another `ES6 --> ES5`, to make them readable by the browser.
### Installation of Babel:
`npm install babel-loader babel-core --save-dev`
#### Basic `.babelrc` config:
```
{
"presets": ["env"]
}
```
#### Integrating it with Webpack:
```
module.exports = {
entry: "./src/js/index.js",
output: {
path: path.resolve(__dirname, "public/js"),
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["babel-preset-env"]
}
}
}
]
}
};
```
Upthere, `babel-loader` is told to use the `babel-preset-env` package installed, to establish the transpile parameters set in the `.babelrc` file.
---
### Bringing It to the Browser:
- Now we have produced a bundle for whatever the imaginary app we have in mind, we need to give it a purpose, run it into the browser!
```
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Webpack & Babel Demonstration</title>
</head>
<body>
<div id='root'></div>
<script src="./public/js/bundle.js" charset="utf-8"></script>
</body>
</html>
```
### Results:
- As configured above, our build system is pretty much ready to go. We can now use webpack to bundle our modules and transpile ES6 code down to ES5 with Babel.
### Dev-ish:
- Now, with the configurations and the `build` script written above, it will be hard for us to `watch` over changes while in development mode, it will be like, writing some code, save it, then run the `npm run build` command again and finally reload the page to see what our changes look like.
#### Webpack WATCH:
To overcome the need to repeatedly run npm run build, you can set up a 'watch' on your files and have webpack recompile automatically every time it sees a change in one of the files in the ./src folder. To implement that:
1. we install _webpack-dev-server_ which will be responsible for the auto refresh in the browser:
`npm install webpack-dev-server --save-dev`
2. We add the watch capability alongside the _webpac-dev-server_ auto refresh.
```
"scripts": {
"start": "webpack --watch & webpack-dev-server --open-page 'webpack-dev-server'",
"build": "webpack --config webpack.config.js"
},
```
---
### [More and more](https://www.sitepoint.com/beginners-guide-webpack-module-bundling/)