Webpack and babel for beginners 👩‍💻
Tags: webpack, babel, javascript, beginners
Published: 2020-08-02 12:24:45

#### What is babel? 
+ Babel is a tool that converts modern Es6 code to older code that older browsers can run. 

#### Let us learn how to set up babel first
 Project name: webpack-prac
+ Install package json it helps to keep track of our packages.
```terminal
 npm init to create a package json 
```
+ Use npm to install babel/core and babel/cli 
babel/cli so that we can use  commands in the command interface to run babel
```terminal
    npm install @babel/core @babel/cli --save-dev
```
##### Note the following
a) Node modules folder - It has function and objects that are used in the application
b) Package-lock.json - Locks down different versions of the packages we are using.
+ Install Babel preset.<br>
This is a setup plugin that supports certain language features and we need in order to convert our code properly. 
+ Install the [babel preset(env)](https://babeljs.io/docs/en/babel-preset-env) and in it in .babelrc file, it helps babel knows which preset to use when running our code.
```terminal
  npm install @babel/preset-env --save-dev
```
##### Create a .babelrc file and write
```json
{
    "presets": ["@babel/preset-env"]
}
```

So far your Package.json should be
```json
{
  "name": "webpack-prac",
  "version": "1.0.0",
  "description": "Intro to webpack and babel",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Jane Muthoni",
  "license": "ISC",
  "devDependencies": {
    "@babel/cli": "^7.10.5",
    "@babel/core": "^7.10.5",
    "@babel/preset-env": "^7.10.4"
  }
}
```

+ Create a index.js file and write 
```js
const destination = (place) =>{
    console.log(` I would love to visit ${place}`);
}
destination();
```

We shall use the babel cli to write commands that convert the modern code to code that can run in older browser versions.In the package.json write the code below
```json
// index.js the file of our modern code and main.js is the output of the older code
"scripts": {
    "babel": "node_modules/.bin/babel index.js -o main.js"
  },

```
In the terminal write 
```terminal
npm run babel
```
Results: Inside the main.js you will see the output of the code.

##### Arrange our files properly
+ Create a distribution folder (dist) that will have the index html file and assets folder that will have the converted js file, images and css files. 
+ The index html file will have a script source of the converted file. In this cause the file will be main.js.
```html
<script src="assets/main.js"></script>
```
+ Then create a source folder (src). It will have our modern javascript files. Create the index.js file in the scr folder and write: 
```js
const destination = (place) =>{
    console.log(` I would love to visit ${place}`);
}
destination('Greece');
destination('Dubai');
destination('Paris');

``` 
##### let's use npm scripts to make our lives easier
+ In the package.json file update the babel script to the code below
 ```json
 "babel": "node_modules/.bin/babel src/index.js -w -o dist/assets/main.js"
 ``` 
In your terminal write 
```terminal
npm run babel. 
```
The -w helps to watch changes inside the index.js file and converts the code every time you save the file. Hence you run npm run babel only once and the changes will be converted automatically.
+ Learn more about [babel](https://babeljs.io/docs/en/)

## Introduction to Webpack
### First webpack flow
[Webpack](https://webpack.js.org/) is an open-source JavaScript module bundler. It is made primarily for JavaScript, but it can transform front-end assets like HTML, CSS, and images if the corresponding loaders are included.
#### let's get started with webpack
+ Create a file in the root directory called webpack.config.js and write
```js
const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist/assets'),
        filename : 'main.js'
    }
}
```
#### install webpack and webpack-cli 
npm install webpack webpack-cli --save-dev
#### Run webpack to bundle your js script. 
+ First create a dom.js file. 

##### How to export functions

#### Method 1
```js
console.log('Dom file');
 
 const body = document.querySelector('body');
 
export const bodyStyle = ()=>{
    body.style.backgroundColor = 'peachpuff';
    body.style.textAlign = 'center';
}
 
export const titleText = (text)=>{
    const title = document.createElement('h2');
    title.textContent = text;
    body.appendChild(title);
}
```

#### Method 2
```js
console.log('Dom file');
 
const body = document.querySelector('body');
 
const bodyStyle = ()=>{
    body.style.backgroundColor = 'peachpuff';
    body.style.textAlign = 'center';
}
 
const titleText = (text)=>{
    const title = document.createElement('h2');
    title.textContent = text;
    body.appendChild(title);
}
 
 
export {bodyStyle, titleText};

```
##### How to import a file and functions
+ Inside the index.js file you can import the functions used in the dom file.
```js
import {bodyStyle, titleText} from './dom';

bodyStyle();
titleText('Hello from the Dom 🔥' );
```
#### Default exports in webpack
+ Default export -  when you are exporting one main thing from the file and can be done only once per file. Example, exporting an array of data in a file.
+ First create a data.js file and create an array of data and export it as default. 
```js
const preminumUsers = [
    {name: 'John', premium: false},
    {name: 'Jane', premium: true},
    {name: 'Kyle', premium: false},
    {name: 'Harry', premium: true},
    {name: 'Luke', premium: true}
];
 
const Activepremium = (users) =>{
    return users.filter(user => user.premium);
}
 
export {Activepremium, preminumUsers as default};

```
+ Import it in our index.js file. You don’t use curly braces because we are importing the default value. So just write the name and from where it’s been imported. 
```js
import {bodyStyle, titleText} from './dom';
import users, { premium } from './data';
 
bodyStyle();
titleText('Hello from the Dom 🔥' );
 
const results = premium(users);
console.log(users , results);

```

+ After importing the default value, write npm run webpack in your terminal to see the data in the console.log
Make webpack automatically get the changes by watching the files (-w)
```json
"scripts": {
    "babel": "node_modules/.bin/babel src/index.js -w -o dist/assets/main.js",
    "webpack": "node_modules/.bin/webpack -w"
  },

```
### Second webpack workflow using webpack dev server
#### Install webpack-dev-server 
Creates a local server
```terminal
npm install webpack-dev-server --save-dev
```
#### Inside the webpack.config.js file, create a devServer object with contentBase and publicPath as it’s property
```js
//inbuilt path method in the node library
const path = require('path');
 
module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist/assets'),
        filename : 'main.js'
    },
    devServer: {
        contentBase: path.resolve(__dirname, 'dist'),
        publicPath: '/assets/'
    }
}
```

Update your package.json file 
```json
"server" : "webpack-dev-server"
```
+ Remember that the  web dev server does not bundle up your code, instead it stores your files virtually. To solve this you have to create a production and development environment. 

+ First click ctrl + c to terminate the web-dev server
Update your package.json file to production and development modes.
```json
"build": "node_modules/.bin/webpack --mode production",
"server" : "webpack-dev-server --mode development"
```

#### In the terminal write npm run server to get the localhost link to your website.
i ｢wds｣: Project is running at http://localhost:8080/

## Babel and webpack together
#### Install babel loader
In your terminal write 
```terminal
npm install babel-loader --save-dev
```
#### In Order for babel to run inside the imported file you have to create an array of rules inside the webpack.config.js file.
One of the rules is to look for js files. We can do this by writing a regular expression.
```js
// looking for files that end with .js
module: {
        rules: [{
            test : /\.js$/
        }]
}
```
+ Write an exclude property inside the rules object, to ensure babel does not include any javascript files from the node_modules folder.
```js
module: {
        rules: [{
            test : /\.js$/,
            exclude : /node_modules/
        }]
}
```
Specify which babel loader and preset you are using by creating a use object
```js
module: {
        rules: [{
            test : /\.js$/,
            exclude : /node_modules/,
            use: {
                loader: 'babel-loader'
            }
        }]
}
```

#### Get the [webpack starter code](https://github.com/muchirijane/webpack-notes)

### In conclusion 🔥
Webpack and babel together is very useful for big projects that can run in any browser. If you have a small project, there is no need to use webpack.There is a lot to know about this topic but these are just the basics. [Webpack](https://webpack.js.org/) and [babel](https://babeljs.io/) official documentation websites should be your guide as you continue learning and building sites.

##### Resources to help you learn babel and webpack
+ [Tutorialspoint](https://www.tutorialspoint.com/babeljs/babeljs_working_babel_with_webpack.htm) website - Working with babel and webpack
+ [Colt Steele](https://www.youtube.com/playlist?list=PLblA84xge2_zwxh3XJqy6UVxS60YdusY8) Youtube channel - Learn webpack course 
+ [Sitepoint](https://www.sitepoint.com/webpack-beginner-guide/) website - A beginner's guide to webpack