JavaScript中使用import 和require打包后实现原理分析


Posted in Javascript onMarch 07, 2018

前言:

之前使用ES6写代码,webpack打包后上线,一点问题没有,也看过打包后的代码,长的很乱,也没敢看看咋回事,加载后就是能运行!

今天通过个例子理解一下打包前,和打包后的代码!

1.创建文件夹,并在里面创建两个文件夹,app文件夹和public文件夹,app文件夹用来存放原始数据和我们将写的JavaScript模块,public文件夹用来存放之后供浏览器读取的文件(包括使用webpack打包生成的js文件以及一个 index.html 文件)。接下来我们再创建三个文件:

  • index.html --放在public文件夹中;
  • Greeter.js -- 放在app文件夹中;
  • main.js -- 放在app文件夹中;

此时项目结构如下图所示

项目结构

我们在 index.html 文件中写入最基础的html代码,它在这里目的在于引入打包后的js文件(这里我们先把之后打包后的js文件命名为 bundle.js ,之后我们还会详细讲述)。

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="utf-8">
  <title>sample Project</title>
 </head>
 <body>
  <div id='root'>
  </div>
  <script src="bundle.js"></script>
 </body>
</html>

我们在 Greeter.js 中定义一个返回包含问候信息的 html 元素的函数,并依据CommonJS规范导出这个函数为一个模块:

// Greeter.js
exports.greet= function() {
 var greet = document.createElement('div');
 greet.textContent = "Hi there and greetings!";
 return greet;
};
exports.USER_INFO = "userInfo";

main.js 文件中我们写入下述代码,用以把 Greeter模块 返回的节点插入页面。

//main.js 
 let {greeter,USER_INFO} =require('./Greeter.js');
console.log(USER_INFO);
document.querySelector("#root").appendChild(greeter());

使用webpack打包后:

(function(modules){     var installedModules = {};  function __webpack_require__(moduleId) {
    if (installedModules[moduleId]) {
      return installedModules[moduleId].exports;
    }
    var module = installedModules[moduleId] = {
      i: moduleId,
      l: false,
      exports: {}
    };
    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    module.l = true;
    return module.exports;
  }
  __webpack_require__.m = modules;
  __webpack_require__.c = installedModules;
  __webpack_require__.d = function(exports, name, getter) {
    if (!__webpack_require__.o(exports, name)) {
      Object.defineProperty(exports, name, {
        configurable: false,
        enumerable: true,
        get: getter
      });
    }
  };
  __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;
  };
  __webpack_require__.o = function(object, property) {
    return Object.prototype.hasOwnProperty.call(object, property);
  };
  __webpack_require__.p = "";
  return __webpack_require__(__webpack_require__.s = 0);
})
(
[
(function(module, exports, __webpack_require__) {
  //main.js
  let {
    greeter,
    USER_INFO
  } = __webpack_require__(1);
  console.log(USER_INFO);
  document.querySelector("#root").appendChild(greeter());
}),
(function(module, exports) {
  // Greeter.js
  exports.greet = function() {
    var greet = document.createElement('div');
    greet.textContent = "Hi there and greetings!";
    return greet;
  };
  exports.USER_INFO = "userInfo";
})
]);

首先最为层是包裹着立即执行函数(加粗的内容),参数是一个数组,数组中每一项是对应的模块,每个模块包裹在 (function(module, exports, __webpack_require__) {//模块内容 });

立即执行函数运行执行  return __webpack_require__(__webpack_require__.s = 0);

也就是执行传入数组中的第一个模块main.js

将运行后的每个模块挂载到installedModules = {}上,当下个需要这个模块直接返回当前模块,不在运行代码块了!

接下来将require改为import看看打包后的如何实现

我们将 Greeter.js的信息改为如下 :

// Greeter.js
export default function() {
 var greet = document.createElement('div');
 greet.textContent = "Hi there and greetings!";
 return greet;
};
export const USER_INFO = "userInfo";
main.js 文件中的代码,修改后
//main.js 
import greet,{USER_INFO} from './Greeter.js';
console.log(USER_INFO);
document.querySelector("#root").appendChild(greet());

然后我们再次打包:

(function(modules) {
  var installedModules = {};
  function __webpack_require__(moduleId) {
    if (installedModules[moduleId]) {
      return installedModules[moduleId].exports;
    }
    var module = installedModules[moduleId] = {
      i: moduleId,
      l: false,
      exports: {}
    };
    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    module.l = true;
    return module.exports;
  }
  __webpack_require__.m = modules;
  __webpack_require__.c = installedModules;
  __webpack_require__.d = function(exports, name, getter) {
    if (!__webpack_require__.o(exports, name)) {
      Object.defineProperty(exports, name, {
        configurable: false,
        enumerable: true,
        get: getter
      });
    }
  };
  __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;
  };
  __webpack_require__.o = function(object, property) {
    return Object.prototype.hasOwnProperty.call(object, property);
  };
  __webpack_require__.p = "";
  return __webpack_require__(__webpack_require__.s = 0);
})([(function(module, __webpack_exports__, __webpack_require__) {
  "use strict";
  Object.defineProperty(__webpack_exports__, "__esModule", {
    value: true
  });
  var __WEBPACK_IMPORTED_MODULE_0__Greeter_js__ = __webpack_require__(1);
  //main.js
  console.log(__WEBPACK_IMPORTED_MODULE_0__Greeter_js__["a"]);
  document.querySelector("#root").appendChild(Object(__WEBPACK_IMPORTED_MODULE_0__Greeter_js__["b"])());
}),
(function(module, __webpack_exports__, __webpack_require__) {
  "use strict";
  __webpack_exports__["b"] = (function() {
    var greet = document.createElement('div');
    greet.textContent = "Hi there and greetings!";
    return greet;
  });;
  const USER_INFO = "userInfo";
  __webpack_exports__["a"] = USER_INFO;
})]);

总结

以上所述是小编给大家介绍的JavaScript中使用import 和require打包后实现原理分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript实现的使用方向键控制光标在table单元格中切换
Nov 17 Javascript
基于jquery的一个OutlookBar类,动态创建导航条
Nov 19 Javascript
jQuery 定时局部刷新(setInterval)
Nov 19 Javascript
再次分享18个非常棒的jQuery表格插件
Apr 10 Javascript
JS上传图片前实现图片预览效果的方法
Mar 02 Javascript
JavaScript动态修改背景颜色的方法
Apr 16 Javascript
js实现网页抽奖实例
Aug 05 Javascript
jQuery实现的数值范围range2dslider选取插件特效多款代码分享
Aug 27 Javascript
js 模仿锚点定位的实现方法
Nov 19 Javascript
Angularjs实现控制器之间通信方式实例总结
Mar 27 Javascript
详解Vue中的基本语法和常用指令
Jul 23 Javascript
在vue中对数组值变化的监听与重新响应渲染操作
Jul 17 Javascript
Vue-cli项目获取本地json文件数据的实例
Mar 07 #Javascript
在vue项目中,使用axios跨域处理
Mar 07 #Javascript
vue中axios解决跨域问题和拦截器的使用方法
Mar 07 #Javascript
node下使用UglifyJS压缩合并JS文件的方法
Mar 07 #Javascript
angularjs使用gulp-uglify压缩后执行报错的解决方法
Mar 07 #Javascript
Vue+ElementUI实现表单动态渲染、可视化配置的方法
Mar 07 #Javascript
浅谈webpack打包之后的文件过大的解决方法
Mar 07 #Javascript
You might like
PHP遍历二维数组的代码
2011/04/22 PHP
PHP Curl出现403错误的解决办法
2014/05/29 PHP
PHP使用 Imagick 扩展实现图片合成,圆角处理功能示例
2019/09/09 PHP
JavaScript Event学习第五章 高级事件注册模型
2010/02/07 Javascript
Jquery Validation插件防止重复提交表单的解决方法
2010/03/05 Javascript
基于jquery实现的鼠标拖拽元素复制并写入效果
2011/08/23 Javascript
Javascript基础教程之函数对象和属性
2015/01/18 Javascript
Javascript验证方法大全
2015/09/21 Javascript
学习javascript面向对象 javascript实现继承的方式
2016/01/04 Javascript
javascript从定义到执行 你不知道的那些事
2016/01/04 Javascript
BootStrap初学者对弹出框和进度条的使用感觉
2016/06/27 Javascript
Three.js如何用轨迹球插件(trackball)增加对模型的交互功能详解
2017/09/25 Javascript
微信小程序自定义toast的实现代码
2018/11/16 Javascript
微信小程序实现工作时间段选择
2019/02/15 Javascript
vue-cli3中vue.config.js配置教程详解
2019/05/29 Javascript
vue-router懒加载的3种方式汇总
2021/02/28 Vue.js
利用Python实现图书超期提醒
2016/08/02 Python
Python OpenCV 直方图的计算与显示的方法示例
2018/02/08 Python
Python 十六进制整数与ASCii编码字符串相互转换方法
2018/07/09 Python
python入门:这篇文章带你直接学会python
2018/09/14 Python
解决pycharm安装后代码区不能编辑的问题
2018/10/28 Python
Python3 安装PyQt5及exe打包图文教程
2019/01/08 Python
django项目环境搭建及在虚拟机本地创建django项目的教程
2019/08/02 Python
Python网页解析器使用实例详解
2020/05/30 Python
在python下实现word2vec词向量训练与加载实例
2020/06/09 Python
python 深度学习中的4种激活函数
2020/09/18 Python
简历自我评价怎么写呢?
2014/01/06 职场文书
中专毕业生自我鉴定
2014/02/02 职场文书
火车来了教学反思
2014/02/11 职场文书
竞聘书格式及范文
2014/03/31 职场文书
过程装备与控制工程专业求职信
2014/07/02 职场文书
大学教师师德师风演讲稿
2014/08/22 职场文书
工商局领导班子存在的问题整改措施思想汇报
2014/10/05 职场文书
护士医德考评自我评价
2015/03/03 职场文书
工作犯错保证书
2015/05/11 职场文书
有关三国演义的读书笔记
2015/06/25 职场文书