Today, let's implement a basic version of Webpack

preface

In essence, webpack is a static module bundler for modern JavaScript applications. When webpack processes an application, it recursively builds a dependency graph containing each module required by the application, and then packages all these modules into one or more bundles.

This is the official website's explanation of webpack. When it comes to modules, as the name implies, modules are independent JS files. The similar word modularization is an implementation of our usual method of organizing and managing code.

Pre war preparation

Let's test the packaging of webpack first.

initialization

  1. Create project directory
mkdir webpackmini
  1. Installing webpack dependencies
yarn add webpack -D

or

npm install webpack -D
  1. The installation of webpack cli depends on here. Please note that we can download this version. The latest version does not seem to be available after installation.
yarn add webpack-cli@3.3.12 -D

or

npm install webpack@3.3.12 -D

Create entry file

  1. Create project home directory
mkdir src
  1. Create entry file
touch main.js
  1. Edit entry file

We use the simplest line of code here.

console.log('maomin1');

Creating and editing a webpack profile

Type the command at the root of the project:

touch webpack.config.js

And edit.

const path = require('path');

module.exports = {
    mode:'development',
    entry:'./src/main.js',
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'bundle.min.js'
    }
}

Run test packaging

Here we use the npx webpack command for packaging. Package succeeded!

When we come to the packaged bundle.min.js file, we will see the following code:

/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
/******/ (() => { // webpackBootstrap
/******/  var __webpack_modules__ = ({

/***/ "./src/main.js":
/*!*********************!*\
  !*** ./src/main.js ***!
  \*********************/
/***/ (() => {

eval("console.log('maomin1');\n\n//# sourceURL=webpack://webpackmini/./src/main.js?");

/***/ })

/******/  });
/************************************************************************/
/******/  
/******/  // startup
/******/  // Load entry module and return exports
/******/  // This entry module can't be inlined because the eval devtool is used.
/******/  var __webpack_exports__ = {};
/******/  __webpack_modules__["./src/main.js"]();
/******/  
/******/ })()
;

After we delete the notes, we will simplify a lot!

(() => {
 var __webpack_modules__ = ({
        "./src/main.js":
        (() => {eval("console.log('maomin1');\n\n//# sourceURL=webpack://webpackmini/./src/main.js?");})
 });

 var __webpack_exports__ = {};
 __webpack_modules__["./src/main.js"]();
})();

Prepare for actual combat

Start to implement a basic version of webpack.

  1. First, we create a folder under the project root directory.
mkdir maominpack
  1. Then, create a bin folder under the Maomin pack folder
mkdir bin
  1. Finally, create a maominpack.js file in the bin folder

Edit as follows:

#!/usr/bin/env node
const fs = require('fs');
const ejs = require('ejs');
const config = require('../../webpack.config.js');

const entry = config.entry;
const output = `${config.output.path}\/${config.output.filename}`;
const content = fs.readFileSync(entry,'utf8');

let template = `
(() => { 
    var __webpack_modules__ = ({
    
    "<%-entry%>":
    (() => {
    
    eval("<%-content%>");
    
    })
    
         });
         var __webpack_exports__ = {};
         __webpack_modules__["<%-entry%>"]();
         
     })()
    ;
`

let package = ejs.render(template,{
    entry,
    content
});

fs.writeFileSync(output,package);

First, we specify the node environment in the header and introduce the fs module. Then, we introduced ejs dependency. If you don't know much about ejs, you can browse the official website. Here is a brief introduction.

What does "E" stand for? It can mean Embedded, Effective, Elegant, or Easy. EJS is a simple template language that helps you generate HTML pages using ordinary JavaScript code. EJS has no dogma on how to organize content; Nor does it recreate a set of iteration and control flow syntax; Some are just ordinary JavaScript code.

We see that when assigning a string with binding value to the template variable, the first parameter ejs.render() we use here is the string to be processed, and the second parameter makes the value we need to modify an object.

  1. Edit under package.json file as follows:
{
  "name": "maominpack",
  "version": "1.0.0",
  "bin":{
    "maominpack":"bin/maominpack.js"
  },
  "main": "index.js",
  "license": "MIT"
}
  1. Create shortcuts to their commands
npm link 
  1. You can also use this command to configure it in other directories
npm config ls
  1. Validate packaging

Let's modify src/main.js.

console.log('maomin2');

Then type the command:

maominpack

Finally, check bundle.min.js:

(() => { 
    var __webpack_modules__ = ({
    
    "./src/main.js":
    (() => {
    
    eval("console.log('maomin2');");
    
    })
    
         });
         var __webpack_exports__ = {};
         __webpack_modules__["./src/main.js"]();
         
     })()
    ;

Found that we packed it successfully. Here, we just implemented the most basic string replacement packaging function. webpack also has many features worth playing with.

Posted on Wed, 01 Dec 2021 07:20:13 -0500 by genista