美文网首页Web前端之路让前端飞java全栈
webpack2是如何对实现es6 modules的

webpack2是如何对实现es6 modules的

作者: MetaZZZZ | 来源:发表于2017-02-26 10:54 被阅读2126次

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

相关文章

  • webpack2是如何对实现es6 modules的

    webpack是如何实现module的呢?我们从最后的文件分析我们先创建两个文件 然后在webpack中设置app...

  • Angualr 2介绍 Essentials

    Modules ES6 style modules没明白: kick off 开始做某事

  • ES6模块

    英文原文,中文原文 modules是ES6引入的最重要一个特性。 所以以后再写模块,直接按照ES6的modules...

  • 页面是如何加载ES6 Modules

    什么是模块 模块就是javascript文件以不同方式去加载(这个就和scripts的方式相反了,scripts是...

  • webpack1/2/3区别

    一、 Webpack2 VS Webpack1新增了许多新特性,需要处理配置语法兼容 增加对 ES6 模块的原生支...

  • ES6-let

    ES6是js语言的国际标准,js是ES6的实现。 检测浏览器对的ES6的支持程度 tracecur转码器将es6翻...

  • webpack2教程续之eslint检测

    本文承接webpack2教程以及webpack2教程续之自动编译,本文所说的项目目录依旧是webpack2 在上两...

  • React Native 如何导入和导出js模块

    import 属于ES6 modules写法 require 属于ES5 ,属于 nodejs 的 commonj...

  • javascript之模拟类继承

    前言 ES6时代的来临,使得类继承变得如此的圆滑。但是,你有思考过ES6的类继承模式吗?如何去实现它呢? 类继承对...

  • webpack2教程续之DllPlugin

    本文承接webpack2教程、webpack2教程续之自动编译以及webpack2教程续之eslint检测,本文所...

网友评论

    本文标题:webpack2是如何对实现es6 modules的

    本文链接:https://www.haomeiwen.com/subject/fognwttx.html