webpack打包之无依赖模块

一、入口文件main.js

// main.js
console.log('webpack');

二、出口文件bundle.js

1、浏览代码

2、本质

// 实际就是一个自执行函数

(function(modules) {
    //...
 })([function(module,exports){
   console.log('webpack');
 }])

这个自执行函数接收一个参数,这个参数是一个模块数组,这个数组里存放我们打包的入口模块,以及这个模块的依赖模块,在这里我们没有依赖模块。

三、代码解读

1、定义一个对象

用来缓存加载进来的模块(加载进来和加载完毕是两个概念)。

// The module cache
/******/    var installedModules = {};

2、声明一个函数

用来加载模块。该函数接收一个moduleId为参数,moduleId就是webpack打包时,你在命令行看到的最下面一行打包文件的详细信息的最开头的数字。

moduleid

function __webpack_require__(moduleId) {
    //...
}

下面,进入该函数内部继续分析。

A、检查函数是否被缓存

为了防止重复打包,这里需要检查该函数是否已经被加载了,进而保证每个模块只会被加载一次。

// Check if module is in cache
if(installedModules[moduleId]) {
    return installedModules[moduleId].exports;
}

B、创建一个module对象

该对象有3个属性,i是index的缩写,表示moduleid;l是loaded的缩写,表示是否已经被加载;exports是对象,用来加载依赖。

// Create a new module (and put it into the cache)
var module = installedModules[moduleId] = {
    i: moduleId,
    l: false,
    exports: {}
};

C、执行传进来的模块

因为main.js没有任何依赖模块,因此,该模块函数没有第三个参数,__webpack_require__也不会被传进去。

// Execute the module function
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

D、修改l的值,返回module.exports

// Flag the module as loaded
module.l = true;

// Return the exports of the module
return module.exports;

3、为函数添加属性方法

A、m(module)的赋值

// expose the modules object (__webpack_modules__)
__webpack_require__.m = modules;

B、c(cache)的赋值

// expose the module cache
__webpack_require__.c = installedModules;

C、d的赋值,更改当前加载进来的模块的属性配置

进入该方法前,判断了一下__webpack_require__上是否有o方法,来确定加载进来的模块是否是入口模块,因为入口模块总是被第一个加载进来,o方法会在d方法后面被定义。

// define getter function for harmony exports
/******/    __webpack_require__.d = function(exports, name, getter) {
/******/        if(!__webpack_require__.o(exports, name)) {
/******/            Object.defineProperty(exports, name, {
/******/                configurable: false,
/******/                enumerable: true,
/******/                get: getter
/******/            });
/******/        }
/******/    };

D、n的赋值,根据模块加载机制的不同做出不同的响应,module.__esModule为es6模块加载机制。

// getDefaultExport function for compatibility with non-harmony modules
/******/    __webpack_require__.n = function(module) {
/******/        var getter = module && module.__esModule ?
/******/            function getDefault() { return module['default']; } :
/******/            function getModuleExports() { return module; };
/******/        __webpack_require__.d(getter, 'a', getter);
/******/        return getter;
/******/    };

E、o的赋值,包装一下Object.prototype.hasOwnProperty。

/******/    // Object.prototype.hasOwnProperty.call
/******/    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };

F、p的赋值

// __webpack_public_path__
/******/    __webpack_require__.p = "";

4、返回函数

// Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = 0);

四、总结

对于没有依赖模块的模块来说,上面说的几乎没用。毕竟webpack是用来进行模块打包的,只有一个模块,webpack的作用就发挥不了了。

原文地址:https://www.cnblogs.com/camille666/p/webpack_no_depend_module.html