С точки зрения простоты понимания nodejs JavaScript в импорта и экспорта спецификации модуля CommonJS

предисловия (предисловия)

Недавно прочитал «nodejs разработать реальные» технари время, есть примеры, когда nodejs в CommonJS модуль спецификации, примеры можно сделать вывод, что если module.exports как экспорт, то приоритет является наивысшим.

Мне очень интересно, и его рабочий механизм есть что?

О в небольшой загрузки И наконец, nodejs коды от WebPack упаковывают в JS кода, и под углом JS как окно.

Поэтому, в этой статье, я хочу сделать, это положить упакованный JS код для демонтажа и проанализировано один за другим, чтобы понять режим работы, вероятно, позади него.

пример (случай)

Прежде всего, мы даем Кодекс nodejs случая:

/commonjs/lib.js:

exports.hello = 'world'

module.exports = function minus (a, b) {
  return a - b
}

exports.add = function (a, b) {
  return a + b
}

/commonjs/index.js:

var lib = require('./lib.js')

console.log(lib)

Наш выход на узел CommonJS / index.js, терминал минус этой функции.

Затем мы выполняем скрипт: WebPack --devtool ни --mode = развитие --target узла CommonJS / index.js

Он будет генерировать DIST папки в нашей корневой директории, и создает файл, в котором main.js:

main.js:

/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// 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;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./commonjs/index.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./commonjs/index.js":
/*!***************************!*\
  !*** ./commonjs/index.js ***!
  \***************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

var lib = __webpack_require__(/*! ./lib.js */ "./commonjs/lib.js")

console.log(lib)



/***/ }),

/***/ "./commonjs/lib.js":
/*!*************************!*\
  !*** ./commonjs/lib.js ***!
  \*************************/
/*! no static exports found */
/***/ (function(module, exports) {

exports.hello = 'world'

module.exports = function minus (a, b) {
  return a - b
}

exports.add = function (a, b) {
  return a + b
}


/***/ })

/******/ });

Таким образом, в общей сложности 124 строк кода (комментарии и пустые строки много, должно быть не менее 100 строк кода, или только пятьсот шестьдесят семь восемьдесят строк), это не займет много времени, чтобы закончить, но мы должны понять это.

Модуль сплит (разделение модулей)

Весь адаптивный код анонимной функции, мы первый код на две части: тело функции , параметры .

параметры

Сначала мы начнем с параметрами логики в основном теле функции, параметры по отношению к относительно простым:

{
  "./commonjs/index.js": (function (module, exports, __webpack_require__) {
      var lib = __webpack_require__("./commonjs/lib.js")
      console.log(lib)
  }),
  "./commonjs/lib.js": (function (module, exports) {
      exports.hello = 'world'
      module.exports = function minus(a, b) {
          return a - b
      }
      exports.add = function (a, b) {
          return a + b
      }
  })
}

Я избавлюсь от параметров в дополнительном комментарии, что приведенный выше код. Это объект, объект имеет две функции типа свойств, легко видеть, что мы можем, прежде чем мы упакованы два файла сценария --commonjs / index.js и CommonJS / lib.js, представители двух функций структура параметров в основном такой же, как первые два параметра и экспорт модуля, index.js из-за введения в lib.js, так что мы должны требовать дополнительного параметра (код для __webpack_require__), то есть, прежде чем мы последовали две функций в естественных условиях точно такой же сценарий в файле сценария.

Функция тела

var a = function (modules) { // webpackBootstrap
  // The module cache
  var installedModules = {};

  // The require function
  function __webpack_require__(moduleId) {

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

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

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

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


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

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

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

  // define __esModule on exports
  __webpack_require__.r = function (exports) {
      if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
          Object.defineProperty(exports, Symbol.toStringTag, {
              value: 'Module'
          });
      }
      Object.defineProperty(exports, '__esModule', {
          value: true
      });
  };

  // create a fake namespace object
  // mode & 1: value is a module id, require it
  // mode & 2: merge all properties of value into the ns
  // mode & 4: return value when already ns object
  // mode & 8|1: behave like require
  __webpack_require__.t = function (value, mode) {
      if (mode & 1) value = __webpack_require__(value);
      if (mode & 8) return value;
      if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
      var ns = Object.create(null);
      __webpack_require__.r(ns);
      Object.defineProperty(ns, 'default', {
          enumerable: true,
          value: value
      });
      if (mode & 2 && typeof value != 'string')
          for (var key in value) __webpack_require__.d(ns, key, function (key) {
              return value[key];
          }.bind(null, key));
      return ns;
  };

  // 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;
  };

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

  // __webpack_public_path__
  __webpack_require__.p = "";


  // Load entry module and return exports
  return __webpack_require__(__webpack_require__.s = "./commonjs/index.js");
}

Это один, можно разделить на три общую логику: __webpack_require__ функции , __webpack_require__ функции дополнительных свойства , возвращаемую функции .

1 .__ функция webpack_require__

Мы ориентируемся на эти несколько строк кода:

  • Это структура данных модуля:
// Create a new module (and put it into the cache)
var module = installedModules[moduleId] = {
    i: moduleId,
    l: false,
    exports: {}
};

  • В связи с началом анонимной структуры параметров функции - (модуль экспорта, требуется), экспорт подмножество объектного модуля, если дать новый объект module.exports, экспорт был заброшен, поэтому здесь, мы знаем, почему Если мы используем module.exports, то module.export будет экспорт покрыт.
// Execute the module function
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  • Это один, мы обеспокоены тем, окончательный возврат, выход module.exports, это на самом деле код в двух предыдущих параграфах, мы можем ожидать.
// Flag the module as loaded
module.l = true;

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

Затем мы пошли посмотреть.

вернуться 2. Функции

На самом деле, вся выполнение кода только последний большой, что в свою очередь, это вызывает только __webpack_require__, так что мы просто смотрим на этот на линии.

Он прошел путь строку, только анонимный параметр функции index.js скриптовых функций, соответствующие имя атрибута, в соответствии с функцией оператора __webpack_require__ сначала создает объект модуля, а затем выполнить следующее заявление:

var lib = __webpack_require__("./commonjs/lib.js")
console.log(lib)

В чем __webpack_require __ ( «./ CommonJS / lib.js») также является объектом для создания модуля, и управляется с помощью сценария на lib.js модуль, а затем вернулся в module.exports Lib код выше.

Здесь, импорт и экспорт операционных модули механизма мы получили немного понятнее очертание, таким образом, для внедрения экспорта между модулями, в основном отвечают нашим потребностям.

Дополнительные функции 3 .__ webpack_require__ недвижимость

Эта часть кода, и эта демо на самом деле ничего делать, но менталитет для более близкого взгляда, или читать немного.

Эти два являются собственностью с открытыми модулями (анонимная функция прошла в Сенате, я здесь, давайте называть его хорошо для модуля очереди) и installedModules (это начало кода декларирует используется модуль кэш данных переменной, в основном, а модуль данных Флаг и moduleId полученный состав)

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

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

Следующая функция является функцией полезности для свойства объекта, чтобы добавить геттер.

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

EsModule используется для установки следующее предложение указано в целевом экспорта, в частности, как использовать, так как это демо не используется, пока не ясно. (Вероятно, думая, что должно быть в направлении сценария, используя этот метод будет использоваться при EsModule экспорта из-за время, что эта статья больше не продолжает проверено)

// define __esModule on exports
  __webpack_require__.r = function (exports) {
      if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
          Object.defineProperty(exports, Symbol.toStringTag, {
              value: 'Module'
          });
      }
      Object.defineProperty(exports, '__esModule', {
          value: true
      });
  };

Следующее предложение объявляется личной догадкой структуры экспорта данных модуля EsModule на основе.

  // create a fake namespace object(声明一个假的命名空间对象)
  // mode & 1: value is a module id, require it
  // mode & 2: merge all properties of value into the ns
  // mode & 4: return value when already ns object
  // mode & 8|1: behave like require
  __webpack_require__.t = function (value, mode) {
      if (mode & 1) value = __webpack_require__(value);
      if (mode & 8) return value;
      if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
      var ns = Object.create(null);
      __webpack_require__.r(ns);
      Object.defineProperty(ns, 'default', {
          enumerable: true,
          value: value // module.exports
      });
      if (mode & 2 && typeof value != 'string')
          for (var key in value) __webpack_require__.d(ns, key, function (key) {
              return value[key];
          }.bind(null, key));
      return ns;
  };

Так как фразы и увидеть модуль модуль .__ esModule возврата [ «по умолчанию»], в общем случае может быть определена в соответствии с типом спецификации модуля, выберите другой модуль сбора данных метод выведения, в котором для получения EsModule getDefault об экспортном умолчанию производный данные.

// 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;
  };

Определить, содержит ли объект атрибута.

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

Это путь, в частности, общественный путь представляет то, что не ясно.

// __webpack_public_path__
  __webpack_require__.p = "";

легенда

Here Вставка рисунка Описание
Наконец, я сделал диаграмму на основе личного понимания. На основании приведенного выше анализа, если выше модель, мы можем представить себе, nodejs при работе с, возможно, первым, чтобы иметь сценарий приобрести набор модулей ModuleSet (Этот модуль основан на сценарии входа начал набор, набор всех связанных модулей ) я указал с ввода карты, то входные данные, передаваемые в сценарий еще раз это ModuleSet сценарий сценарий, мы предполагаем, что это функция, функция начала расширяться с точки входа методами требуется.

последний (конечный)
Спасибо вы закончите читать эту статью, ваше чтение моей мотивации продолжать двигаться вперед.

Для выше, каких новых идей или найти что-то не так, я надеюсь, что вы можете указать.

Наконец, приложите отдельные часто посещают социальные платформы:
знают почти: https://www.zhihu.com/people/bi-an-yao-91/activities
CSDN: https://blog.csdn.net/YaoDeBiAn
GitHub: https://github.com/yaodebian

Личный текущий ограниченный потенциал, и не существует никакой независимой способности создать сообщество, если у вас есть какие-либо вопросы или идеи, общаться со мной, пожалуйста, свяжитесь со мной через одну из этих платформ, спасибо! ! !

Опубликовано 80 оригинальные статьи · вона похвала 91 · Просмотров 150,000 +

рекомендация

отblog.csdn.net/YaoDeBiAn/article/details/104736252