Webpack packaging Javascript details

Posted by paragkalra on Wed, 08 Dec 2021 07:02:54 +0100

In this article, we mainly introduce webpack packaging Javascript. Of course, in addition to Javascript, webpack can also package html. But this is not the focus of this article. We can refer to Webpack HTML packaging introduction

Now let's extend a project -- Web pack - Example (Click Webpack installation View the initialization of the project) and specify custom names for the entry and output properties. In webpack.config.js, we add the following before the plugins attribute:

entry: {
  main: path.resolve(__dirname, './src/app.js'),
},
output: {
  filename: '[name].bundle.js',
  path: path.resolve(__dirname, 'deploy')
},

The complete code is shown below

webpack.config.js file

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require('path');

module.exports = {
    entry: {
        main: path.resolve(__dirname, './src/app.js'),
      },
      output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'deploy')
      },
    plugins: [
        new HtmlWebpackPlugin({
            hash: true,
            title: 'Webpack - Trace memory guest(jiyik.com)',
        })
    ],
};

We don't use html templates here

Here, we change the entry file to app.js and the output folder to deploy. We also slightly adjusted the name of the generated package file. It will now begin with the name of the entry ("main"), followed by the word "bundle" and the. js file extension.

Now let's create the src/component.js file:

src/component.js

export default (text = "Hello, Webpack!!") => {
  const element = document.createElement("h1");

  element.innerHTML = text;

  return element;
};

Next, we rename index.js in the current project to app.js to reflect our changes, and replace its contents with the following:

app.js

import component from './component';

document.body.appendChild(component());

Now let's run the webpack and see what happens

$ npm run dev

> webpack-example@1.0.0 dev /Users/jiyik/workspace/js/webpack-example
> webpack --mode development

asset main.bundle.js 4.33 KiB [emitted] (name: main)
asset index.html 552 bytes [emitted] [compared for emit]
runtime modules 670 bytes 3 modules
cacheable modules 235 bytes
  ./src/app.js 77 bytes [built] [code generated]
  ./src/component.js 158 bytes [built] [code generated]
webpack 5.54.0 compiled successfully in 142 ms

After running, we will see the deploy folder generated in the project directory, which contains static html files and js files

At this time, we run the deploy/index.html file in the browser, and the results are as follows:

In addition, if we check the source code of index.html, we will see that the value of src attribute in script tag is updated to main.bundle.js.

At this point, we can delete the dist folder originally generated by webpack because we no longer need it.

Convert ES6 to ES5

Next, we'll learn how to convert ES6 into ES5 code for all browsers. Let's start by running the following command:

$ npm run dev -- --devtool inline-source-map

Here, I run webpack and set the devtool option to inline source map to make the code more readable. This can more clearly demonstrate the transcoding from ES6 to ES5.

Now let's open main.bundle.js

main.bundle.js partial code

/***/ "./src/component.js":
/*!**************************!*\
  !*** ./src/component.js ***!
  \**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((text = "Hello, Webpack!") => {
    const element = document.createElement("h1");
  
    element.innerHTML = text;
  
    return element;
  });

/***/ })

/******/ 	});

As you can see, modern ES6 features (arrow functions and const declarations) from the component.js module are not converted to ES5 compliant code by default. In order for our code to work in the old browser, we must add a Babel loader:

$ npm install babel-loader @babel/core @babel/preset-env --save-dev

Then, in the webpack.config.js file, add the module item after the output item, as shown below

module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    },
  ]
},

When defining rules for webpack loader, we usually need to define three main attributes:

  • test - it describes what files should be converted.
  • exclude - it defines files that should not be processed from the loader.
  • use - it tells which loader should be used for matching modules. Here, we can also set the loader option, just like the presets option we just completed.

webpack.config.js

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require('path');

module.exports = {
    entry: {
        main: path.resolve(__dirname, './src/app.js'),
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'deploy')
    },
    module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: ['@babel/preset-env']
              }
            }
          },
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Webpack - Trace memory guest(jiyik.com)',
        })
    ],
};

Then run the webpack to see what kind of files will be generated

$ npm run dev -- --devtool inline-source-map

> webpack-example@1.0.0 dev /Users/liuhanzeng/workspace/js/webpack-example
> webpack --mode development "--devtool" "inline-source-map"

asset main.bundle.js 7.02 KiB [emitted] (name: main)
asset index.html 257 bytes [compared for emit]
runtime modules 670 bytes 3 modules
cacheable modules 301 bytes
  ./src/app.js 76 bytes [built] [code generated]
  ./src/component.js 225 bytes [built] [code generated]
webpack 5.54.0 compiled successfully in 1340 ms

The code in main.bundle.js this time:

/***/ "./src/component.js":
/*!**************************!*\
  !*** ./src/component.js ***!
  \**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (function () {
  var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "Hello, Webpack!";
  var element = document.createElement("h1");
  element.innerHTML = text;
  return element;
});

/***/ })

/******/ 	});

Perfect. Now that we can use modern JS functionality (ES6), webpack will transform our code so that it can be executed by old browsers.

The complete Webpack can be referenced Webpack tutorial

Topics: Javascript Front-end Programming Webpack