# Webpack Essentials

### Let's unpack what a module bundler is and why we need it.

A module bundler intelligently creates a bundle for us, like which module depends on which to create a dependency graph. It can make certain transformations on our modules before adding them to our bundle. <mark>e.g. transforming SASS to CSS or ES6 to ES5 using BABEL</mark>.

### How to install Webpack?

```bash
npm install webpack webpack-cli --save-dev
```

### Webpack configurations:

We make a config file named `webpack.config.js` file. It exports an object -

```javascript
// webpack.config.js file

module.exports = {
    // we write our webpack configurations here...
};
```

### Webpack needs to know 3 things to create a bundle(s)

### 1\. entry point of our app

In the `webpack.config.js` file we need to write an `entry` property

```javascript
// webpack.config.js file

module.exports = {
    entry: "./app/index.js"
};
```

### 2\. which transformations

Loaders for getting the ability to process different types of files. By default, we have only the ability to process `.js` and `.json` files.

<mark>e.g. svg loader</mark>

Let's install svg loader

```bash
npm install svg-inline-loader --save-dev
```

We need to add some configuration `rules` for `svg-inline-loader` in the `module` property

```javascript
// webpack.config.js

module.exports = {
    entry: "./app/index.js",
    module: {
        rules: [
            {
                test: /\.svg$/,
                use: "svg-inline-loader"
            }
        ],
    },
};
```

<mark>e.g. css loader</mark>

Let's install `css-loader`

```bash
npm install css-loader --save-dev
```

Now, we need to add configuration rules for `css-loader`

```javascript
// webpack.config.js

module.exports = {
    entry: "./app/index.js",
    module: {
        rules: [
            {
                test: /\.svg$/,
                use: "svg-inline-loader"
            },
            {
                test: /\.css$/,
                use: "css-loader"
            }
        ],
    },
};
```

Adding these rules will allow us to import CSS files in our application, but this <mark>doesn't mean</mark> that those CSS styles are injected into the DOM to be active.

For that we need `style-loader`

```bash
npm install style-loader --save-dev
```

Add `style-loader` element to the `use` property of `rules`

```javascript
// webpack.config.js

module.exports = {
    entry: "./app/index.js",
    module: {
        rules: [
            {
                test: /\.svg$/,
                use: "svg-inline-loader"
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
            }
        ],
    },
};
```

<mark>e.g. babel loader</mark>

Let's install `babel-loader`

```bash
npm install babel-loader --save-dev
```

Add `babel-loader`

```javascript
// webpack.config.js

module.exports = {
    entry: "./app/index.js",
    module: {
        rules: [
            {
                test: /\.svg$/,
                use: "svg-inline-loader"
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
            },
            {
                test: /\.(js)$/,
                use: "babel-loader"
            }
        ],
    },
};
```

### 3\. output location of bundle

Finally, we need to tell our bundler where we need to put the output of the bundler in the `output` property.

This is how our `webpack.config.js` file will look finally.

```javascript
// webpack.config.js
const path = require("path");

module.exports = {
    entry: "./app/index.js",
    module: {
        rules: [
            {
                test: /\.svg$/,
                use: "svg-inline-loader"
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
            },
            {
                test: /\.(js)$/,
                use: "babel-loader"
            }
        ],
    },
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "index-bundle.js"
    }
};
```

### What's the difference between Loaders and Plugins?

Loaders work on the files before or while the bundle is generated.

Plugins execute tasks after the bundle is created. In general, plugins are more powerful than loaders.
