mode

The Mode configuration option, which tells Webpack to use the built-in optimization for response Mode:

The default value is production

Optional values are: ‘none’ | ‘development’ | ‘production’

module.exports = {
  mode: 'development'.// Mode is the top-level configuration option

  entry: './src/index.js'.output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/main.js',},plugins: [
    new CleanWebpackPlugin(),

    new HtmlWebpakcPlugin()
  ]
}
Copy the code

Modular Implementation Principle

#All of the following modularization implementation principles are available in the following versions:
$ webpack --version
#Webpack 5.46.0
#Webpack - cli 4.7.2
Copy the code

webpack.config.js

module.exports = {
 mode: 'development'.// Set devtool to 'source-map' before starting modularization debugging
 // Since mode is set to development, devtool's default value is set to eval
 // The compiled code is actually unreadable
 devtool: 'source-map',}Copy the code

ES Module

/ / module
export const sum = (num1, num2) = > num1 + num2

/ / the main module
import { sum } from './js/math'
console.log(sum(3.5))
Copy the code
// The packaged js file ---- is an IIFE that uses strict mode - it is executed immediately after loading
// For ease of reading, some variables are replaced with variable names
(function() {
  "use strict";
  // webpack_modules is an object, key is the module's path, value is a function, and the function body is the previously defined code in the module
  var webpack_modules = {
    "./src/js/math.js":
    // __unused_webpack_module is the module object passed in -- {export: {... }}
    // But this object is not used, just placeholder, so call it __unused_...
    (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

    // Label the exported object
    __webpack_require__.r(__webpack_exports__)

    // Mount the sum function on the exported object
    __webpack_require__.d(__webpack_exports__, {
      "sum": function() { return sum }
    })

    // Code previously defined in math.js
    const sum = (num1, num2) = > num1 + num2
    })
  }

  // An empty object used to cache module data
  var cache = {}

  // a function, parsing the module
  function __webpack_require__(moduleId) {
    // If there is a cache, take the value directly from the cache
    var cachedModule = cache[moduleId]
    if(cachedModule ! = =undefined) {
      return cachedModule.exports
    }

    // No cache, use continuous assignment so that module and chche[moduleId] point to the same object
    // {exports: {}} -- The export object
    var module = cache[moduleId] = {
      exports: {}}// Fetch the diAM defined in the module and execute it
    webpack_modules[moduleId](module.module.exports, __webpack_require__)

    // Return the exported data
    return module.exports
  }

  // Mount the exported data to the object where the exported data is stored
  !function() {
    /* Parameter 1: the object where the exported data is stored parameter 2: the data to be exported */
    __webpack_require__.d = function(exports, definition) {
      // Iterate over the exported data object itself
      for(var key in definition) {
        // Set the exported data to the proxy
        if(__webpack_require__.o(definition, key) && ! __webpack_require__.o(exports, key)) {
          Object.defineProperty(exports, key, { enumerable: true.get: definition[key] })
        }
      }
    }
  }()

  // Pass in a property and determine if the property is a property of the passed object
  !function() {
    __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop) }
  }()


  // IIFE adds a label to the exported object to indicate that the object is used to store the exported content of the module after Webpack has resolved it
  !function() {
    __webpack_require__.r = function(exports) {
      // If the browser supports Symbol, output [object Module] when calling (export object).tostring ()
      if(typeof Symbol! = ='undefined' && Symbol.toStringTag) {
        Object.defineProperty(exports.Symbol.toStringTag, { value: 'Module'})}// Each exported module has an attribute __esModule with a value of true
      Object.defineProperty(exports.'__esModule', { value: true}}}) ()var __webpack_exports__ = {}

  // IIFE master module
  !function() {
  // Label the module
  __webpack_require__.r(__webpack_exports__)

  // Import the module and store the exported data
  var mathModuleObj_ = __webpack_require__("./src/js/math.js")

  console.log(mathModuleObj_.sum(3.5))
  }()
})();
Copy the code

The above code is simplified as follows

!function() {
  // webpack_modules is the module mapping, key is the module path, value is the function, and the function body is the previously defined code in the module
  var module_map = {
    "./src/js/math.js":
    /* Parameter 1: module object parameter 2: object to store exported data parameter 3: custom function to parse the imported module (used when other modules are introduced in the module) */
    (function(__exports, __require) {
      addTag()
      
      // Code previously defined in math.js
      const sum = (num1, num2) = > num1 + num2
      // Mount exposed data
      __exports.sum = sum
    })
  }

  // An empty object used to cache module data
  var cache = {}

  // a function, parsing the module
  function __require(moduleId) {
    // If there is a cache, take the value directly from the cache
    if (cache[moduleId]) {
      return cache[moduleId].exports
    }

    // No cache, use continuous assignment so that module and chche[moduleId] point to the same object
    // {exports: {}} -- The export object
    var module = cache[moduleId] = {
      exports: {}}// Execute the module to store the exported data in a predefined object
    module_map[moduleId](module.exports, __require)

    // Return the exported data
    return module.exports
  }
  
  // Use the ESM tag to distinguish between ESM modules and CJS modules
  function addTag() {
    if(typeof Symbol! = ='undefined' && Symbol.toStringTag) {
      Object.defineProperty(exports.Symbol.toStringTag, { value: 'Module'})}// Add the attribute __esModule value to true
    Object.defineProperty(exports.'__esModule', { value: true})}// Execute the main module
  !function() {
    addTag()
    var { sum } = __require("./src/js/math.js")
    console.log(sum(3.5))
  }()
}()
Copy the code

Common JS modularity

/ / module
const sum = (num1, num2) = > num1 + num2
module.exports.sum = sum

/ / the main module
const { sum } = require('./js/math')
console.log(sum(3.5))
Copy the code
// The compiled js file is still an IIFE
(function() {
  // Module mapping key is the module path, value is the function body is the module corresponding code body
  var __webpack_modules__ = ({
    "./src/js/math.js":
    (function(module) {
      const sum = (num1, num2) = > num1 + num2
      module.exports.sum = sum
    })
  });

  / / cache
  var __webpack_module_cache__ = {};

  // The custom require method is the same as ESM's custom require method
  function __webpack_require__(moduleId) {
    var cachedModule = __webpack_module_cache__[moduleId];
    if(cachedModule ! = =undefined) {
      return cachedModule.exports;
    }
    var module = __webpack_module_cache__[moduleId] = {
      exports: {}}; __webpack_modules__[moduleId](module.module.exports, __webpack_require__);

    return module.exports;
  }


  var __webpack_exports__ = {};

  // IIFE executes the main module
  !function() {
  const { sum } = __webpack_require__("./src/js/math.js")

  console.log(sum(3.5))} (); }) ();Copy the code

ESM and CJS call each other

It can be seen from the modularization principle of ESM and CJS that the modularization transformation mode of ESM and CJS is basically the same in Webpack

So ESM and CJS calls to each other are supported in Webpack

// Export the ESM module
module.exports.format = () = >console.log('format')

// CJS module export
export const sum = (num1, num2) = > num1 + num2

/ / the main module

// CJS export, ESM import
import { format } from './js/format'
// ESM export, CJS import
const { sum } = require('./js/math')

// Function call
format()
console.log(sum(2.5))
Copy the code