webpack2是如何对实现es6 modules的

webpack是如何实现module的呢?
我们从最后的文件分析
我们先创建两个文件

a.js

 let a = 1
 const b = 2
 export function log(val) {
  console.log(val)
}
export default{
  a:a,
  b:b
}


app.js

import tt from './a'
import {log} from './a'
console.log(tt.b)
log(tt.b)

然后在webpack中设置app.js为入口,打包一下...

webpack 会根据入口文件的依赖读入所有依赖的js,最后生成一个文件(默认配置),在文件中具体的看下面


ps:最后打包好都是在一个文件中,这里先拿出其中一部分分析

先看a.js在打包文件中是什么样子

function(module, __webpack_exports__, __webpack_require__) {

  "use strict";
  /* harmony export (immutable) */ __webpack_exports__["b"] = log;
  let a = 1
  const b = 2
  function log(val) {
    console.log(val)
  }
  /* harmony default export */ __webpack_exports__["a"] = {
    a:a,
    b:b
  };
}

可以看到webpack首先将整个文件包裹了起来,添加了三个变量,然后将export的属性都绑定到了__webpack_exports__


再看app.js

function(module, __webpack_exports__, __webpack_require__) {

  "use strict";
  Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
  /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__a__ = __webpack_require__(0);


  console.log(__WEBPACK_IMPORTED_MODULE_0__a__["a" /* default */].b)
  __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__a__["b" /* log */])(__WEBPACK_IMPORTED_MODULE_0__a__["a" /* default */].b)


  /***/ }

对比原app.js

import tt from './a'
import {log} from './a'
console.log(tt.b)
log(tt.b)

__webpack_require__(0)就是返回模块export的模块

可以看到,import 在这里就是创了一个含有导入模块export的对象,在下面调用模块时,去这个对象中调用.


下面来看__webpack_require__

(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: {}
  };

  // 执行了导入的module,把export的值都放到module.exports中
  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;

// identity function for calling harmony imports with the correct context
__webpack_require__.i = function(value) { return value; };

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

// 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 = 1);
})
  /************************************************************************/
([
  /* 0 */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {

  "use strict";
  /* harmony export (immutable) */ __webpack_exports__["b"] = log;
  let a = 1
  const b = 2
  function log(val) {
    console.log(val)
  }
  /* harmony default export */ __webpack_exports__["a"] = {
    a:a,
    b:b
  };


  /***/ }),
  /* 1 */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {

  "use strict";
  Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
  /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__a__ = __webpack_require__(0);


  console.log(__WEBPACK_IMPORTED_MODULE_0__a__["a" /* default */].b)
  __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__a__["b" /* log */])(__WEBPACK_IMPORTED_MODULE_0__a__["a" /* default */].b)


  /***/ })
]);

这里用了一个立即执行函数,把所有的模块做为一个数组传了进去,在初始化之后,调用了入口模块return __webpack_require__(__webpack_require__.s = 1); 1就是入口模块所在的数组index,然后在调用入口模块时,递归的加载入口模块调用的模块,比如: 在入口模块中

 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__a__ = __webpack_require__(0);

这就会去加载其他的模块,将其他模块中的export变量导入到入口模块中,供给模块内部使用.

总结

es6 module是静态的依赖,所以在运行前进行代码转换,这里的实现是将所有导出项作为一个对象的属性,在入口文件执行时,去递归的加载模块

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,081评论 7 35
  • GitChat技术杂谈 前言 本文较长,为了节省你的阅读时间,在文前列写作思路如下: 什么是 webpack,它要...
    萧玄辞阅读 12,613评论 7 110
  • 学习流程 参考文档:入门Webpack,看这篇就够了Webpack for React 一. 简单使用webpac...
    Jason_Zeng阅读 3,048评论 2 16
  • 在现在的前端开发中,前后端分离、模块化开发、版本控制、文件合并与压缩、mock数据等等一些原本后端的思想开始...
    Charlot阅读 5,386评论 1 32
  • 那年冬月27, 风雪交加,冷得出奇, 没有火炉,没有水,没有电, 你就在学校一个巴掌大的陋室诞生了。 虽然又黑又瘦...
    春的守望阅读 251评论 0 2