Webpack setup for beginners. Basic commands with code exampl... open

Webpack setup for beginners. Basic commands with code examples

Webpack is a tool for bundling web applications. It allows you to break your code into modules and collect them in one or more files, thereby reducing the number of requests to the server and the size of downloaded files.

The main function of Webpack is to analyze and combine the various resources of your project, such as JavaScript files, CSS files, images and other resources, into a format that can be used by a browser.

Node and npm instalation

For Webpack to work, we need npm, it is installed together with node.js
What is npm
npm (Node Package Manager) is the standard package manager for JavaScript and the Node.js runtime. It is used to manage project dependencies, including installing, updating, removing, and other operations with JavaScript packages.

Let’s check the node version, open a terminal on your computer and type the command into it:

node -v
Check node version
Check node version

If we saw the version of node, it means that it is already installed on our computer, if you did not see the version, use the instructions on the official website of node.jsnodejs.org

After installing node, we can install npm itself.
npm must be installed directly in your project. To do this, open a terminal in the project or go to it using the command:

cd path/to/your/project

Now that we are in our project, we can initialize npm by entering the following command in the terminal:

npm init -y

After successful initialization, a package.json file will appear in the root of your project.

What is in the package.json file?
The package.json file usually contains information about the project, such as name, version, description, authors, project dependencies, and other settings used by npm to manage the project and its dependencies

Webpack instalation

If we successfully initialized npm, we can start installing Webpack itself, for this, enter the command in the terminal:

npm install webpack -D
Install Webpack log message
Install Webpack log message

After that, a new property called devDependencies will appear in the package.json file and in it we will see the settings of our WebPack.

Dependencies webpack
Dependencies webpack

Webpack CLI

The next step is to enter the command in the terminal:

npm install webpack-cli

The npm install webpack-cli command installs a command line interface (CLI) for Webpack that allows you to use Webpack from the command line of your operating system.

Once webpack-cli is installed, you will be able to call Webpack commands directly from the command line. For example, you can call the webpack command to start building your project using the webpack.config.js configuration file.

Webpack local server

If we need a local server, enter the command in the terminal:

npm install webpack-dev-server -D

webpack-dev-server is a package that provides a development server specifically designed for use with Webpack. It allows you to quickly deploy a local server to test your code while developing a web application.

All of these will also appear in devDependencies:

Webpack dev server in devDependencies

Configure startup commands

Let’s open the package.json file located at the root of our project and find “scripts” property in it.

Each element of the scripts property is a key-value pair, where the key is the name of the command that you will call from the command line, and the value is the command or set of commands that will be executed when that command is called.

Add our commands:

"scripts": {
  "start": "webpack serve", //starts our webpack virtual server
  "build-dev": "webpack",//runs a test build of our project
  "build-prod": "webpack --node-env=production",//runs our final production build
  "clear": "rd /s /q dist"//clear our dist folder
}

To use our commands in the terminal we write:

npm run "command-name"

For example:

npm run build-prod

Webpack.config.js

The webpack.config.js file is a configuration file for Webpack that is used to define build options for your JavaScript code. It needs to be created in the roots of our project next to the package.json file.

Here is an example of such a file:

const path = require('path');

module.exports = {
  entry: './src/index.js', // Entry point where bundling begins
  output: {
    path: path.resolve(__dirname, 'dist'), // Path to the directory where the compiled code will be saved
    filename: 'bundle.js' // Collected file name
  },
  module: {
    rules: [
      {
        test: /\.js$/, // Regular expression to select JavaScript files
        exclude: /node_modules/, // Excluding files from processing
        use: {
          loader: 'babel-loader', // JavaScript transpilation loader (e.g. Babel)
          options: {
            presets: ['@babel/preset-env'] // Set of transpilation rules
          }
        }
      }
    ]
  },
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'), // Directory from which static content will be served
    port: 9000 // Port on which the dev server will be launched
  }
};

We’ll modify it a little:

const path = require('path');

const mode = process.env.NODE_ENV || 'development'; //explicitly specify the bundling type

const devMode = mode == 'development'; //check whether we have a development bundling

const target = devMode ? 'web' : 'browserslist'; //if we have a build for specific browsers

const devtool = devMode ? 'source-map' : 'undefined'; //if we do not have a production build, then we will not add a sourcemap

module.exports = {

	//add our constants as object properties
	mode,
	target,
	devtool,

 	entry: path.resolve(__dirname, 'src', 'index.js'), // Let's use our index.js file in the src directory
 	output: {
    path: path.resolve(__dirname, 'dist'), 
    filename: 'index.[contenthash].js' // The name of the collected file with the version to reset the caching
    clean: true, //let's clean up our directory
  },
  
};

Now we need to add a file with a list of browsers .browserslistrc to the root of our project. We will add to this file:

last 2 versions
not dead
> 0.5%

Work with HTML files

Now you need to add a plugin for WebPack that works with HTML. Enter the following command in the terminal:

npm install --save-dev html-webpack-plugin

Now let’s add our plugin to the webpack.config.js file:

const path = require('path');



//Add our plugin <--------------
const HtmlWebpackPlugin = require('html-webpack-plugin');


const mode = process.env.NODE_ENV || 'development'; 

const devMode = mode == 'development'; 

const target = devMode ? 'web' : 'browserslist'; 

const devtool = devMode ? 'source-map' : 'undefined'; 

module.exports = {

	mode,
	target,
	devtool,

 	entry: path.resolve(__dirname, 'src', 'index.js'), 
  output: {
    path: path.resolve(__dirname, 'dist'), 
    filename: 'index.[contenthash].js' 
    clean: true, 
  },


  //Let's create an instance <--------------
  plugins: [
  new HtmlWebpackPlugin({
  	template:path.resolve(__dirname,'src', 'index.html')//Write the path
  }),

  ],
  
};

The html document created by us that will be displayed on local hosting must be reloaded every time. In order for index.html to be updated automatically, add it to the terminal:

npm install --save-dev html-loader

Now let’s write it in the settings of our webpack.config.js file:

module: {
    rules: [
      {
        test: /\.html$/, // Regular expression to select JavaScript files
        loader: 'html-loader',
      }
    ]
  },

Let’s add tracking to our index.js file:

import './index.html';

Work with styles

style-loader helps you include CSS styles directly in your application’s JavaScript code, which is convenient for development and for working with other tools to compile and optimize your project.

Let’s add it to the terminal:

npm install --save-dev style-loader

Also add css-loader:

npm install --save-dev css-loader

Let’s add our modules to the rules of the webpack.config.js file:

module: {
    rules: [
      {
        test: /\.html$/, 
        loader: 'html-loader',
      }

      {
        test: /\.css$/i, //Regular expression to select css files
        use: ["style-loader", "css-loader"],//our modules
      },

    ]
  },
 

Now add CSS tracking to our index.js file:

import './index.css';
Second line CSS tracking
Second line CSS tracking

So that our styles are not added to the body of the html, let’s install the plugin:

npm install --save-dev mini-css-extract-plugin

Connect our plugin in the same way as connecting an html plugin:

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

Add our plugin to webpack.config.js:

plugins: [
    new HtmlWebpackPlugin({
        template: path.resolve(__dirname, 'src', 'index.html')//write the path
    }),

    new MiniCssExtractPlugin({
        filename: 'index.[contenthash].css',
    })

],

Add rule:

module: {
    rules: [
        {
            test: /\.html$/, 
            loader: 'html-loader',
        },

        {
            test: /\.css$/i,
            use: [
                devMode ? "style-loader" : MiniCssExtractPlugin.loader, //our rule
                "css-loader"
            ],
        },

    ]
},

SCSS support

SASS (Syntactically Awesome Style Sheets) is an advanced syntax language for CSS that adds powerful interpretation capabilities to regular CSS. The main purpose of SASS is to facilitate and improve the process of writing and maintaining styles for websites and web applications.

Change in the module settings:

{
    test: /\.(c|sa|cs)css$/i, //search for css sass scss
    use: [
        devMode ? "style-loader" : MiniCssExtractPlugin.loader,
        "css-loader"
    ],
}

Let’s connect the module with analogy as we did before:

npm install sass-loader sass -D

Let’s add this in the module settings:

{
    test: /\.(c|sa|sc)ss$/i,
    use: [
        devMode ? "style-loader" : MiniCssExtractPlugin.loader,
        "css-loader",
        'sass-loader'//our module
    ],
},

Now we can rename our index.css file to index.scss:

Rename CSS to SCSS
Rename CSS to SCSS

let’s go to our index.js file and change import './index.css'; on import './index.scss';

Autoprefixes

Add the following commands to the console:

npm install --save-dev postcss-loader postcss
npm install postcss-preset-env --save-dev

postcss-loader allows you to process CSS using PostCSS plugins. PostCSS is a tool that allows you to perform various automatic operations on CSS, such as auto-prefixes, optimization, adding or removing vendor prefixes, etc. postcss-loader integrates PostCSS into your Webpack configuration to automate CSS handling when building your project.

postcss is the core of PostCSS, without which PostCSS plugins will not work. It contains basic functions and interfaces for processing CSS using various plugins.

postcss-preset-env is a PostCSS plugin that provides the ability to use modern CSS features that may not yet be officially supported in all browsers. It automatically analyzes your CSS and automatically adds the necessary prefixes and polyfills to ensure compatibility with different versions of browsers.

Let’s add these modules to webpack.config.js:

{
    test: /\.(c|sa|sc)ss$/i,
    use: [
        devMode ? "style-loader" : MiniCssExtractPlugin.loader,
        "css-loader",
            {
                loader: "postcss-loader",
                options: {
                    postcssOptions: {
                        plugins: [require('postcss-preset-env')],
                    }
                }
            },
        'sass-loader'
    ],
},

Server config

The devServer settings in the Webpack configuration are used to configure the local development server. Here’s a brief description of each of these settings:

devServer: {
    port: 3000,
    open: true,
    hot: true,
}
  • port: 3000 – this option sets the port on which the local server will run. In this case, the server will be available at http://localhost:3000/.
  • open: true – when set to true, this will automatically open the browser when starting the local server.
  • hot: true – this setting enables Hot Module Replacement (HMR). Hot swapping of modules allows you to make changes to the code and see them immediately in the browser without reloading the page

Work with JS

First, let’s install Bebel, a JavaScript transpilation tool that allows developers to write code in the latest version of JavaScript without worrying about whether all browsers and runtimes support it.

npm install -D babel-loader @babel/core @babel/preset-env 

Let’s add Bebel for JS in the webpack.config.js file:

{
    test: /\.(?:js|mjs|cjs)$/,
    exclude: /node_modules/,
    use: {
        loader: "babel-loader",
        options: {
            presets: [
                ["@babel/preset-env", { targets: "defaults" }],
            ],
        },
    },
},

Also add a polyfill, this will ensure compatibility of the code with older versions of JavaScript and different browsers:

npm install --save @babel/polyfill

Тепер замінимо в webpack.config.js:

entry: path.resolve(__dirname, "src", "index.js"),

on

entry: ['@babel/polyfill', path.resolve(__dirname, "src", "index.js")],

Fonts

In webpack.config.js, add dependencies for fonts:

{
    test:/\.woff2?$/i,
    type: 'assets/resource',
    generator: {
        filename: 'fonts/[name][ext]'
    }
}

Now we will add the fonts.scss file to the style directory of our project. In the file, we will connect our fonts:

@font-face {
    font-family: 'Montserrat';
    src: url('fonts/montserrat.woff') format('woff2'), url('fonts/montserrat.woff2') format('woff'); //write the paths relative to the index.scss file
}

Now import these fonts into the index.scss file:

@import 'style/fonts';

Images

Let’s add dependencies to our webpack.config.js file:

{
    test:/\.(jpe?g|png|webp|gif|svg)$/i,
    type: 'assets/resource',
}

Optimize the size of images. Let’s add a package:

npm install image-webpack-loader --save-dev

Let’s connect our package:

{
    test: /\.(jpe?g|png|webp|gif|svg)$/i,

        use: [
            {
                loader: 'image-webpack-loader',

                options: {
                    mozjpeg: {
                        progressive: true,
                    },
                    // optipng.enabled: false will disable optipng
                    optipng: {
                        enabled: false,
                    },
                    pngquant: {
                        quality: [0.65, 0.90],
                        speed: 4
                    },
                    gifsicle: {
                        interlaced: false,
                    },
                    // the webp option will enable WEBP
                    webp: {
                        quality: 75
                    }

                }
            }
        ]

    type: 'assets/resource',
}

Full webpack.config.js file


const path = require("path");

const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const mode = process.env.NODE_ENV || "development"; //specify the build type

const devMode = mode == "development"; //check if we have a development project build

const target = devMode ? "web" : "browserslist"; //if we have a build for specific browsers

const devtool = devMode ? "source-map" : "undefined"; //if we do not have a production build, then we will not add a sourcemap

module.exports = {
    mode,
    target,
    devtool,

    devServer: {
        port: 3000,
        open: true,
        hot: true,
    },

    entry: path.resolve(__dirname, "src", "index.js"), // Use our index.js file in the src directory
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "index.[contenthash].js", // Name of the collected file with the version to reset the caching
        assetModuleFilename: 'assets/[name][ext]',
        clean: true, //Clean up our director
    },

    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "src", "index.html"), //Write the path
        }),

        new MiniCssExtractPlugin({
            filename: "index.[contenthash].css",
        }),
    ],

    module: {
        rules: [
            {
                test: /\.html$/, // Regular expression to select JavaScript files
                loader: "html-loader",
            },

            {
                test: /\.(?:js|mjs|cjs)$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: [
                            ["@babel/preset-env", { targets: "defaults" }],
                        ],
                    },
                },
            },

            {
                test: /\.(c|sa|sc)ss$/i,
                use: [
                    devMode ? "style-loader" : MiniCssExtractPlugin.loader,
                    "css-loader",
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [require("postcss-preset-env")],
                            },
                        },
                    },
                    "sass-loader",
                ],
            },

            {
                test: /\.woff2?$/i,
                type: 'assets/resource',
                generator: {
                    filename: 'fonts/[name][ext]'
                }
            },

            {
                test: /\.(jpe?g|png|webp|gif|svg)$/i,
            
                    use: [
                        {
                            loader: 'image-webpack-loader',
            
                            options: {
                                mozjpeg: {
                                    progressive: true,
                                },
                                // optipng.enabled: 
                                optipng: {
                                    enabled: false,
                                },
                                pngquant: {
                                    quality: [0.65, 0.90],
                                    speed: 4
                                },
                                gifsicle: {
                                    interlaced: false,
                                },
                                // the webp option will enable WEBP
                                webp: {
                                    quality: 75
                                }
            
                            }
                        }
                    ],
            
                type: 'assets/resource',
            }

        ],
    },
};

0

More

Comments (1)

Leave a Reply

Your email address will not be published. Required fields are marked *

How many?: 22 + 22

lil-code© | 2022 - 2024
Go Top
Authorization
*
*
Registration
*
*
*
*
Password generation